【问题标题】:Page loading progressively页面逐步加载
【发布时间】:2015-05-15 14:06:15
【问题描述】:

我正在构建一个基本的抓取工具,在我的笔记本电脑上本地运行,以从 cms 备份数据。

我编写的基本程序脚本会从数据库加载 url,对于每个 url,它会删除页面,将内容保存到数据库,然后回显页面已成功保存。

问题在于,当它设法一次通过所有 url(有时数百个)时,脚本的输出会逐渐加载到我的浏览器中。

在 Firefox 中,我可以看到一些页面的部分 echo 语句(表明页面已保存),其余部分分批出现,并且在底部 Firefox 显示“正在从 localhost 传输数据...”

我很困惑,因为我认为当 php 脚本运行时,它只会在完成后将响应作为单个块输出和发送,而不是这样,逐步进行。

也许我忘记了我的代码中的某些内容?你怎么看?

这是我的脚本的基本结构:

<?php

try {
  // Login into the CMS
  // Connect to the DB to get the urls

  for ($i = 0; $i < count($urls); $i++) {
    // Get data from page
    $data = $scraper->getData($urls[$i]);

    // Store data from page
    if ( $db->save($data) ) {
      echo 'Data successfully saved for "' . $url[$i] . '"<br>';
    } else {
      echo 'Problem when saving data for "' . $url[$i] . '"<br>';    
    }
  }
}

catch (Exception $e) {
    echo $e->getMessage() . '<br>';
}

?>

我曾想过使用输出缓冲,但问题是如果脚本失败或超时,那么我认为我根本不会得到任何输出。

【问题讨论】:

  • 你可以在客户端做一些事情来让页面一次性出现,而不是缓冲输出。例如,将所有输出放在&lt;div style="display: none"&gt; 中,然后在处理结束时使用CSS 或JavaScript 更改div 的样式。或者您可以回显一个将显示输出的 JavaScript 函数,并且在处理结束之前不要调用该函数。
  • @Lithis 仍然无法帮助他,因为由于超时,该过程的结束永远不会完成,并且 JS 不会被打印。编辑:实际上,从理论上讲,如果他将 JS 放入 document.ready 中,它将等到脚本停止加载以运行 JS 然后将其全部显示,因此您的解决方案可能会起作用
  • 是的,我的评论不是一个经过深思熟虑的答案,我应该说“在页面加载结束时”而不是“在处理结束时”,但我希望它可能会给某人一个更完整答案的想法。页面加载完成后更改可见性,并希望超时触发脚本。

标签: php for-loop timeout


【解决方案1】:

您想要使用某种类型的输出缓冲区。您也可以将这些附加到一个字符串并在完成后回显该字符串:

<?php

try {
  // Login into the CMS
  // Connect to the DB to get the urls
  $html = '';
  for ($i = 0; $i < count($urls); $i++) {
    // Get data from page
    $data = $scraper->getData($urls[$i]);

    // Store data from page
    if ( $db->save($data) ) {
      $html .= 'Data successfully saved for "' . $url[$i] . '"<br>';
    } else {
      $html .= 'Problem when saving data for "' . $url[$i] . '"<br>';    
    }
  }
  echo $html;
}
catch (Exception $e) {
    echo $e->getMessage() . '<br>';
}

?>

即使脚本没有完成加载,PHP 中的回显也会立即开始发送文档。这就是为什么您会看到它逐行发生。

您还可以查看 ob_start() http://php.net/manual/en/function.ob-start.php 。这是一种标准的回显方式,但在您准备好全部显示之前保持输出。

正如评论中提到的@Lithis,如果您想等待脚本完全停止运行后才显示信息,您可以将其包装在

<div style="display:none"></div>

然后在 document.ready 上使用 Javascript 将显示类型更改为“块”以避免它逐行显示。

【讨论】:

  • 问题是大多数时候,数组中的元素(url)太多,它不会遍历所有元素而是超时。在这种情况下,使用输出缓冲会阻止我看到任何输出吗?
  • 是的,如果超时,输出缓冲会阻止您看到输出。当前处理它的方式是在超时情况下获得输出的唯一方式。如果超时是个问题,您应该使用 ini_set 或 php.net/manual/en/function.set-time-limit.php 来增加允许的时间
猜你喜欢
  • 2015-07-25
  • 2023-03-18
  • 1970-01-01
  • 2011-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-04
  • 2011-07-10
相关资源
最近更新 更多