使用 Javascript 实时读取 PHP 数组的结果
Posted
技术标签:
【中文标题】使用 Javascript 实时读取 PHP 数组的结果【英文标题】:Read results of a PHP array, in real time with Javascript 【发布时间】:2012-09-08 01:11:30 【问题描述】:经过几天的尝试,我当然无法自己解决这个问题。这就是问题所在:
我们需要在屏幕上显示信息(HTML),这是在 PHP 文件中实时生成的。
PHP 正在执行非常主动的爬取,返回大量 URL 数组,每个 URL 都需要在 HTML 中实时显示,一旦 PHP 捕获它,这就是我们使用的原因Ob_flush() 和 flush 方法在我们得到数组后立即回显和打印它们。
同时,我们需要以某种方式显示此信息,以便用户可以在它工作时看到它(因为它可能需要一个多小时才能完成)。
据我所知,使用 AJAX 是不可能的,因为我们只需要发出 1 个请求并读取数组中的信息。我也不确定是否comet 可以做这样的事情,因为它会在获得新信息后立即中断连接,并且数组确实在迅速增加它的大小。
此外,只是为了让事情变得更复杂,实际上不需要打印或回显数组内的信息(URL),因为 html 文件被包含为正在处理和生成的同一文件的用户界面我们需要显示的数组。
长话短说;我们需要放在这里:
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
...
</ul>
在 PHP 循环中生成并推送到数组中的永无止境且实时更新的 URL 列表,下面 1,000 行。
任何帮助都会非常感激。 提前致谢!
【问题讨论】:
将 php 数组写入文件并使用 javascript 解析是否可行?您可以随时对文件进行 ajax 处理,并且在 PHP 不断添加文件时,它会得到所有结果。 您好 Jon,非常感谢您的快速回复,这是一个很好的方法,我们已经在考虑这一点,但是由于负载已经非常大,这是不可能的。 很好奇套接字是否适合您.... 【参考方案1】:尝试网络套接字。
它们提供客户端和服务器之间的实时通信,并使用 socket.io 提供跨浏览器兼容性。它基本上为您提供与长轮询/彗星相同的结果,但请求之间的开销更少,因此速度更快。
在这种情况下,您将使用 Web 套接字向客户端发送有关当前处理状态(或正在执行的任何操作)的更新。
看到这个Using PHP with Socket.io
【讨论】:
我在这里被很多人强迫,不仅仅是发布一个链接作为答案,我建议你也这样做,通过解释为什么 WebSockets 会比已经发布的答案更理想,你是的,这是最好的解决方案.. ;) 我对它们很熟悉,听起来也很有可能,我会看看这个,你有什么解决方案可以建议实现这个吗?非常感谢! 谢谢,我们正在采用这种方法!!【参考方案2】:假设您使用 PHP 写入 Memcached 服务器的方案..
你写成rec1、rec2、rec3的每个键
您还存储一个 current_min 和一个 current_max
您让用户不断地使用 ajax 进行轮询。对于每个请求,他们都包含他们看到的最后一个键,称之为 k。然后服务器返回从k到max的所有记录。
如果没有立即可用的记录,服务器会进入一个最长等待循环,例如 3 秒,每 100 毫秒检查一次是否有新记录
如果记录可用,则会立即发送。
每当客户端收到更新或连接终止时,它们会立即开始新的请求...
写入新记录只需插入 max+1 并递增 min 和 max,其中 max-min 是您希望保持可用的记录数...
【讨论】:
谢谢斯蒂芬,这是一个有趣的方法。你认为它应该比数据库或套接字选项工作得更快吗? 肯定比 db 选项快,因为 memcached 插入/删除将是 O(1) 并且完全存储在内存中。Web Sockets 可能是发送数据的最佳选择,但它们对浏览器的支持有些不一致眼下。 FF 暂时将它们从 FF4 中删除,然后将它们放回 FF5,因为他们发现了标准级别存在的安全问题。 非常感谢斯蒂芬,也是一个很好的解决方案。【参考方案3】:网络套接字的替代品是 COMET
我为此写了an article,以及描述我的经历的a followup。
根据我的经验,COMET 很快。 Web 套接字绝对是未来,但如果您只需要完成它,您可以在一个小时内启动并运行 COMET。
这里肯定需要某种共享内存结构 - 可能是数据库中的内存临时表,或者斯蒂芬已经建议的 Memcached。
【讨论】:
【参考方案4】:我认为最好的方法是让第一个 PHP 脚本将每条记录保存到数据库(可能是 mysql 或 SQLite),然后让第二个 PHP 脚本从数据库中读取并输出最新记录。然后使用 AJAX 每隔一段时间调用这个脚本,并将它发送的记录添加到您的表中。您必须找到触发第一个脚本的方法。
javascript应该记录它已经拥有的最后一个url的id,并在AJAX请求中发送,然后PHP可以选择id大于那个的所有行。
如果 URL 的数量如此之多,以至于您无法在服务器上存储这么大的数据库(有人可能会问浏览器如何处理这么大的表!),那么您总是可以拥有输出最新记录的 PHP 脚本也会将它们从数据库中删除。
编辑:在执行大量 MySQL 插入操作时,您可以做几件事来加快速度。有一个很好的答案here 详细说明了它们。简而言之,使用 MyISAM,并在单个查询中输入尽可能多的行(在 PHP 中有一个缓冲区数组,您可以将 URL 添加到其中,当它已满时,在一个查询中插入整个缓冲区)。
【讨论】:
您好 Gandaliter,非常感谢您的评论!这是我们在系统中完成的最快的实现,我们已经尝试过这种方法,但仍然会对性能产生很大影响,因为它需要大量的插入查询。此外,它还意味着创建第二个文件只是为了读取在同一来源中正在处理的信息。你还有什么想法吗?【参考方案5】:If I were you , I try to solve this with two way .
First of all I encode the output part array with json and with the setTimeout function with javascript I'll decode it and append with <ul id="appendHere"></ul> so
当列表更新时,它会自动更新。就像一个带有 js 的 cronjob 。
第二种方式,如果你说我在处理时无法输出,那么 我认为使用向 mysql 插入数据是没有意义的,使用 MongoDb 等来提高速度。 顺便说一句,您将使用您的密钥达到您需要的内容,并且永远不会重复插入的值。
【讨论】:
以上是关于使用 Javascript 实时读取 PHP 数组的结果的主要内容,如果未能解决你的问题,请参考以下文章
[PHP] php作为websocket的客户端实时读取推送日志文件