php - php 应用程序中的关键代码部分?

标签 php api rest file-upload

好吧,在我看来这有点复杂,我希望我能解释一下。如果有任何不清楚的地方,请发表评论,以便我完善问题。

我想将用户文件上传到第三台服务器。

所以我们有

  • 用户
  • 网站(网站运行所在的服务器)
  • 存储服务器(接收文件)

流程应该是这样的:

  1. 该网站从存储云网关请求一个上传 URL,该 URL 直接指向最终存储服务器(类似 http://serverXY.mystorage.com/upload.php )。与请求一起发送“目标路径”(网站特定且全局唯一)和重定向 URL。

  2. 网站生成一个以存储服务器上传 url 作为目标的上传表单,用户选择一个文件并单击提交按钮。存储服务器处理发布请求,将文件保存到临时位置(即 '/tmp-directory/'.sha1(target-path-fromabove))并将返回重定向到重定向 url已由网站指定。 “目标路径”也被传递。

  3. 如果用户取消进程或连接中断或其他原因,我不希望保留任何“幻影文件”!还必须避免网站数据库中未在存储云中正确处理然后被破坏的条目。这就是这个和下一步的原因

  4. 这些是关键步骤

    • 网站现在将 en 条目写入自己的数据库,并向存储 api(已签名,网站必须使用 secret token 进行身份验证)发出 RESTful 请求
    • 将文件从它在存储服务器上的临时位置复制到它的最终位置(这应该很快,因为它只是重命名)
    • 相同的休息请求还在存储网络数据库中插入一个数据库行以及作为所有者的网站 id
  5. 存储服务器上 tmp 目录中超过 24 小时的所有文件都会自动删除。

如果用户关闭浏览器窗口或连接中断,服务器上的程序流也会中止,对吗? 只执行析构函数和注册的关闭函数,对吗?

我能否以某种方式使此代码部分成为“关键”部分,以便服务器一旦进入此代码部分,就会执行到最后,而不管用户是否中止页面加载?

(当然我知道服务器崩溃或错误随时可能中断,但我现在担心的是正常流程)

我的一个想法是在网站数据库中有一个标志和一个时间戳,将文件标记为“已完成”,并在一个 cronjob 中检查旧的未完成文件,然后从存储云中删除它们,然后从网站数据库中删除它们,但是我真的很想避免这个额外的字段和过程。

我希望存储 api 非常通用,并在未来的许多其他项目中使用它。

我查看了面向开发人员的 Google 存储和 Amazon s3。

他们有同样的问题,甚至更糟。在亚马逊 S3 中,您可以“签署”您的发布请求。所以文件在你的授权下由用户上传,直接保存存储,你要付费。 如果连接中断并且用户永远不会回到您的网站,您甚至都不知道。 因此,您必须存储所有您签名的上传 URL,并在 cronjob 中检查它们,并删除所有未“到达目的地”的内容。

对于该问题有什么想法或最佳做法吗?

最佳答案

如果我没看错,那么当存储服务将用户重定向回您的网站时,您正在执行脚本中的关键操作。

我看到了两个确保关键步骤完整执行的选项:

  1. 确保 PHP 忽略连接状态并使用 ignore_user_abort() 运行脚本直至完成.
  2. 触发一些后端进程,这些进程独立于面向用户的脚本执行关键操作。如果您使用的是 *NIX 服务器(man at 了解更多详细信息),这可能就像将作业放入 at 队列一样简单,也可能像拥有专用队列管理守护进程一样复杂,就像LrdCasimir 建议的那个。

我遇到过的此类问题都有与其操作相关的非常耗时的过程,因此我总是选择选项 2 以向浏览器提供快速响应,并释放 Web 服务器。选项 1 易于实现,但选项 2 最终更容错,因为更新将保留在队列中,直到它们可以成功传送到存储服务器。

connection handling PHP 手册中的页面对 HTTP 连接期间发生的情况提供了很多很好的见解。

关于php - php 应用程序中的关键代码部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5529223/

相关文章:

PHP 从 MySQL 表获取父信息

android - 我如何在 Android 上进行身份验证

java - 何时以及如何在我的 Rest Api 中实例化 Spring Bean

php - 在sql数据库中存储html代码问题

php - 使用 Amazon SNS 使用 PHP AWS SDK v2 发送 SMS 消息?

javascript - React - 提交表单时重定向到第三方网站

Python/Django REST API 架构

python - 如何使用python从Jotform下载数据?

java - 对 Modeshape 休息服务器的 DELETE 请求

php - Laravel 通过自定义属性查询