现代 PHP Web 应用程序的 AJAX 进度指示器是如何实现的?
我见过许多实现进度条的网络应用程序,但是,我的问题与非上传品种有关。
许多 PHP Web 应用程序(phpBB、Joomla 等)都实现了“智能”安装程序,不仅可以指导您完成软件的安装,还可以让您了解其当前正在执行的操作。例如,如果安装程序正在创建 SQL 表或写入配置文件,它会报告此情况,而不要求您单击。 (基本上,坐下来放松安装。)
另一个很好的例子是 Joomla 的 Akeeba Backup(以前称为 Joomla Pack)。当您执行 Joomla 安装的备份时,它会生成安装目录的完整存档。然而,这需要很长时间,因此需要更新进度。然而,服务器本身对 PHP 脚本执行时间有限制,因此似乎
- 备份脚本能够绕过它。
- 存储一些临时数据以便附加存档(如果可以附加存档)。
- 客户端脚本经常调用服务器的 PHP 来执行操作。
我的一般猜测(不是特定于 Akeeba)是#3,即:
Web page JS -> POST foo/installer.php?doaction=1 SESSID=foo2 Server -> ERRCODE SUCCESS Web page JS -> POST foo/installer.php?doaction=2 SESSID=foo2 Server -> ERRCODE SUCCESS Web page JS -> POST foo/installer.php?doaction=3 SESSID=foo2 Server -> ERRCODE SUCCESS Web page JS -> POST foo/installer.php?doaction=4 SESSID=foo2 Server -> ERRCODE FAIL Reason: Configuration.php not writable! Web page JS -> Show error to user
我 99% 确定情况并非如此,因为这会对用户启用 Javascript 产生非常讨厌的依赖。
我想我的问题可以归结为以下几点:
- 长时间运行的 PHP 脚本(当然是在 Web 服务器上)如何处理并能够在 PHP 最大执行时间之后“保持活动状态”?如果他们不“作弊”,他们如何能够分解手头的任务? (我注意到Akeeba Backup确实承认PHP最大执行时间限制,但我不想深入挖掘这样的代码。)
- 通过AJAX+PHP如何显示进度?我读过人们使用文件来指示进度,但对我来说,这似乎“肮脏”,并且给 I/O 带来了一些压力,特别是对于运行上述脚本的拥有 10,000 多个访问者的实时服务器。
该脚本的环境是启用safe_mode的,一般限制为30秒。 (基本上,是一个受限制的、免费的 0 美元主机。)该脚本针对所有受众(将公开),因此我无权决定它将在哪个主机上运行。 (这假设我不会因为主机不好而责怪最终用户。)
我不一定需要代码示例(尽管非常感谢它们!),我只需要知道实现的逻辑流程这。
I've seen many web apps that implement progress bars, however, my question is related to the non-uploading variety.
Many PHP web applications (phpBB, Joomla, etc.) implement a "smart" installer to not only guide you through the installation of the software, but also keep you informed of what it's currently doing. For instance, if the installer was creating SQL tables or writing configuration files, it would report this without asking you to click. (Basically, sit-back-and-relax installation.)
Another good example is with Joomla's Akeeba Backup (formerly Joomla Pack). When you perform a backup of your Joomla installation, it makes a full archive of the installation directory. This, however, takes a long time, and hence requires updates on the progress. However, the server itself has a limit on PHP script execution time, and so it seems that either
- The backup script is able to bypass it.
- Some temp data is stored so that the archive is appended to (if archive appending is possible).
- Client scripts call the server's PHP every so often to perform actions.
My general guess (not specific to Akeeba) is with #3, that is:
Web page JS -> POST foo/installer.php?doaction=1 SESSID=foo2 Server -> ERRCODE SUCCESS Web page JS -> POST foo/installer.php?doaction=2 SESSID=foo2 Server -> ERRCODE SUCCESS Web page JS -> POST foo/installer.php?doaction=3 SESSID=foo2 Server -> ERRCODE SUCCESS Web page JS -> POST foo/installer.php?doaction=4 SESSID=foo2 Server -> ERRCODE FAIL Reason: Configuration.php not writable! Web page JS -> Show error to user
I'm 99% sure this isn't the case, since that would create a very nasty dependency on the user to have Javascript enabled.
I guess my question boils down to the following:
- How are long running PHP scripts (on web servers, of course) handled and are able to "stay alive" past the PHP maximum execution time? If they don't "cheat", how are they able to split the task up at hand? (I notice that Akeeba Backup does acknowledge the PHP maximum execution time limit, but I don't want to dig too deep to find such code.)
- How is the progress displayed via AJAX+PHP? I've read that people use a file to indicate progress, but to me that seems "dirty" and puts a bit of strain on I/O, especially for live servers with 10,000+ visitors running the aforementioned script.
The environment for this script is where safe_mode is enabled, and the limit is generally 30 seconds. (Basically, a restrictive, free $0 host.) This script is aimed at all audiences (will be made public), so I have no power over what host it will be on. (And this assumes that I'm not going to blame the end user for having a bad host.)
I don't necessarily need code examples (although they are very much appreciated!), I just need to know the logic flow for implementing this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一般来说,这种东西存储在 $_SESSION 变量中。就执行超时而言,我通常做的是设置一个 JavaScript 超时,每隔 x 秒将更新状态 div 的 innerHTML 设置为 PHP 脚本。当这个脚本执行时,它不会“等待”或类似的事情。它只是从会话中获取当前状态(通过实际执行安装的脚本进行更新),然后以我认为合适的任何奇特方法(状态栏等)输出该状态。
我不建议使用任何直接 I/O 来更新状态。你是对的,它既混乱又低效。我想说 $_SESSION 绝对是正确的选择。
Generally, this sort of thing is stored in the $_SESSION variable. As far as execution timeout goes, what I typically do is have a JavaScript timeout that sets the innerHTML of an update status div to a PHP script every x number of seconds. When this script executes, it doesn't "wait" or anything like that. It merely grabs the current status from the session (which is updated via the script(s) that is/are actually performing the installation) then outputs that in whatever fancy method I see fit (status bar, etc).
I wouldn't recommend any direct I/O for status updates. You're correct in that it is messy and inefficient. I'd say $_SESSION is definitely the way to go here.