PHP实时显示进度消息

3
我正在使用PHP开发一个处理大量数据的工具,需要一些时间才能完成。我希望让用户了解当前进展和正在处理的任务。您认为最好的方法是什么?我有一些想法,但无法确定哪种方式最有效:

  • 旧方法:执行脚本的一小部分,并显示一个页面给用户,用Meta Redirect或JavaScript计时器发送请求以继续脚本(例如/script.php?step=2)。

  • 不断发送AJAX请求以读取服务器文件,该文件由PHP通过fwrite()不断更新。

  • 与上述相同,但PHP将更新数据库中的字段而不是保存文件。

这些方法中是否有好的?还有其他想法吗?

谢谢!

6个回答

5
与其写入一个通过AJAX获取的静态文件或额外的数据库字段,不如再编写一个PHP脚本,该脚本只返回指定任务的完成百分比。然后,您的页面可以通过非常轻量级的AJAX请求更新进度到该PHP脚本。
至于实现这个“进度”脚本,如果我更了解您所说的“处理大量数据”的含义,我可以提供更多建议。如果您正在写入文件,则“进度”脚本可以简单地检查文件大小并返回完成百分比。对于更复杂的任务,您可以为特定进程分配基准,并根据最后完成的进程或当前运行的进程返回估计的完成百分比。
更新:
这是一种建议的方法,用于“检查”正在等待请求响应的活动脚本的进度。我有一个数据挖掘应用程序,我使用类似的方法。
在使请求的脚本(您要检查进度的脚本)中,您可以将进度变量存储在文件或数据库中(我使用数据库,因为我每时每刻都有数百个进程在运行,所有这些进程都需要跟踪它们的进度,并且我有另一个脚本允许我监视这些进程的进度)。当进程开始时,将其设置为1。您可以轻松选择脚本将通过的任意数量的“检查点”,并根据当前检查点计算百分比。但是,对于大型请求,您可能更想知道请求已完成的大致百分比。一种可能的解决方案是了解返回内容的大小,并根据任何时刻接收到的百分比设置状态变量。即,如果您在循环中接收请求数据,则每次迭代都可以更新状态。或者,如果您要下载到平面文件,则可以轮询文件的大小。如果您知道请求应该花费的大致时间并仅与脚本的当前执行时间进行比较,则可以使用时间(而不是文件大小)进行不太准确的操作。显然,这两种方法都不是完美的解决方案,但我希望它们能为您提供一些选项的见解。

嗨Dustin,该工具是一个Feed爬虫,因此大部分的过程只是等待响应。你如何让另一个PHP脚本“调用”一个活动脚本以获取百分比?谢谢! - Xavi Esteve
我已经更新了一个简短的讨论,讲解你可能如何去做 :) - defines

1

我建议使用 AJAX 方法,而不是使用文件或数据库。您可能可以使用会话值或类似的东西,这样您就不必创建连接或打开文件来执行任何操作。


PHP会话存储在文件中。 - Frank Farmer
不一定,但默认情况下是的。我仍然认为这比您自己阅读和编写要快。 - Kerry Jones
不错,我不知道你可以这样做。这是迄今为止我读过的最简单但最有效的解决方案,但是如何设置会话存储方法呢?如果不是在文件中存储,它们存储在哪里,也许是 RAM 吗?谢谢 Kerry。 - Xavi Esteve
我不会担心会话存储方法,我会让它写入文件,但你可以通过php.ini或可能的.htaccess来实现。它们通常存储在tmp目录中,类似于/var/tmp(每个服务器都有所不同)。如果您在页面上运行phpinfo(),它应该告诉您。 - Kerry Jones
的确,我想我会使用文件方法。不想太多地编辑服务器,并且如果存储在文件中,则信息更加灵活(例如用作API)。 - Xavi Esteve

1
过去,我只是将消息写到页面上并使用flush()来刷新输出缓冲区。非常简单,但它可能无法在每个Web服务器或每个Web浏览器上正常工作(因为它们可能会进行自己的内部缓冲)。
就我个人而言,我最喜欢您的第二个选项。应该是可靠且相当简单易行的。

我经常为我在本地服务器上使用的个人工具这样做(如果只有你一个人会看到它,为什么要费心使用AJAX?),但在生产环境中我不会依赖于此。 - defines

1

我喜欢选项2 - 使用AJAX定期读取PHP写入的状态文件。这将打开许多不同的演示选项。如果您将JSON对象写入文件,则可以轻松解析它并显示诸如进度条、状态消息等内容...


0
一个“不太正规”但快捷易行的方法是在脚本运行时直接输出状态。只要没有开启输出缓存,浏览器就会根据从服务器接收到的内容渲染HTML(我知道WordPress使用这种技术来进行自动升级)。
但是,更好的方法当然是使用AJAX,尽管我认为“分解它”的做法也没有什么问题。
为什么不把1和2结合起来呢?使用AJAX向script.php?step=1发送请求,检查响应,将其写入浏览器,然后再到script.php?step=2获取更多内容,以此类推。

0
如果您可以放弃使用IE,那么请使用服务器发送事件。这是最理想的解决方案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接