可能重复:
how can I achieve a task that should be done in thread in php
通常在PHP中运行PDO查询时,它会等待数据库结果。有没有办法避免这种情况?
我需要我的脚本快速回复,但运行的SQL可能需要一些时间才能运行。
示例:
<?php
$pdo = new PDO('bla bla');
// This takes up to 1 second, but I need the script to reply within a few ms
$pdo->exec('UPDATE large_table SET foo = \'bar\' WHERE id = 42');
die('ok');
这可行吗?
答案 0 :(得分:2)
对于INSERT
次查询,您可以使用INSERT DELAYED
(Manual)。这些查询将被置于工作队列中并立即返回。缺点是您对查询是否成功执行没有任何反馈。
然而,由于不明原因,没有UPDATE DELAYED
...
答案 1 :(得分:1)
常见的方法是首先渲染输出,然后使用flush()
将输出刷新到客户端,然后执行时间消耗查询。您还应该了解ignore_user_abort()
。尽管与客户端的连接可能已经结束,但此函数使PHP保持运行。 (例如用户关闭浏览器)
我准备了两个说明这一点的脚本。首先是slow.php
,它会提前刷新输出,然后开始一个耗时的任务。第二个是get.php
,它使用libcurl来接收页面。如果你测试它,当slow.php仍在运行时,get.php几乎会立即返回。我还用当前的Mozilla测试了慢速php。
slow.php:
// The example will not work unless ob_end_clean() is called
// on top. Strange behaviour! Would like to know a reason
ob_end_clean();
// disable all content encoding as we won't
// be able to calculate the content-length if its enabled
@apache_setenv('no-gzip', 1);
@ini_set('zlib.output_compression', 0);
@ini_set('implicit_flush', 1);
header("Content-Encoding: none");
// Tell client that he should close the connection
header("Connection: close");
// keep the script running even if the CLIENT closes the connection
ignore_user_abort();
// using ob* functions its easy to content the content-length later
ob_start();
// do your output
echo 'hello world', PHP_EOL;
// get the content length
$size = ob_get_length();
header("Content-Length: $size");
// clear ob* buffers
for ($i = 0; $i < ob_get_level(); $i++) {
ob_end_flush();
}
flush(); // clear php internal output buffer
// start a time consuming task
sleep(3);
get.php
// simplest curl example
$url = 'http://localhost/slow.php';
$ch = curl_init($url);
$fp = fopen("example_homepage.txt", "w");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
答案 2 :(得分:0)
通过AJAX调用更新脚本,在您进行更新时向用户显示加载程序。
如果您在页面加载时不需要输出中的查询结果,那么这是唯一的方法。