当从PHP运行长查询时,如果用户在浏览器中按下停止,如何关闭查询?
考虑到我不能调用任何其他PHP函数,因为PHP在等待MySQL时被阻塞。
此外,由于会话锁定,我不能再向服务器(通过Ajax)发出任何请求。
因此,一个解决办法可以是:
我不知道该怎么做的两件事是:
发布于 2011-09-28 14:21:32
对于那些感兴趣的人,我用的是:
<?php
// Connection to query on
$query_con = mysqli_connect($host, $user, $password, $name, $port);
// Connection to kill on
$kill_con = mysqli_connect($host, $user, $password, $name, $port);
// Start the query
$query_con->query($slow_query, MYSQLI_ASYNC);
// Get the PID
$thread_id = $query_con->thread_id;
// Ignore user abort so we can kill the query
ignore_user_abort(true);
do {
// Poll MySQL
$links = $errors = $reject = array($mysqli->mysqli);
$poll = mysqli_poll($links, $errors, $reject, 0, 500000);
// Check if the connection is aborted and the query was killed
if (connection_aborted() && mysqli_kill($kill_con, $thread_id)) {
die();
}
} while (!$poll);
// Not aborted, so do stuff with the result
$result = $link->reap_async_query();
if (is_object($result)) {
// Select
while ($row = $result->fetch_object()) {
var_dump($row);
}
} else {
// Insert/update/delete
var_dump($result);
}发布于 2011-09-28 11:28:48
一旦PHP注意到用户已经停止了请求(在脚本试图向用户输出某些内容之前通常不会发生这种情况),您的脚本就会终止。在关闭之前,PHP调用已激活的任何关闭函数。您可以实现终止查询的关闭函数,并将其注册到register_shutdown_function()。
您可以这样做的另一种方法是在打开ignore_user_abort()的情况下运行脚本,并通过定期调用connection_aborted()来检查用户是否已中止。如果用户已中止,则终止查询并优雅地退出脚本。
有关连接处理这里的更多信息。
发布于 2011-09-28 13:04:34
如果查询所花费的时间是由于返回的大型数据集造成的,则可以使用mysql_unbuffered_query。然后在shutdown_function中,您可以释放结果并从mysql断开连接。
如果您正在使用PHP5.3.x并拥有mysqlnd,您可能可以在mysqli_query中使用MYSQLI_ASYNC,然后使用mysqli_poll来获得结果。
第一个选项只有在检索数据集所花费的时间时才会有所帮助。但是,如果mysql在解析和创建执行计划以及将表加载到内存方面实际上花费了很长时间,那么它不会有帮助。在这种情况下,您需要MYSQLI_ASYNC,它只在PHP 5.3.x和mysqlnd上可用。
另外,如果您的主要问题是session locking,请查看本文中的PHP文档http://php.net/manual/en/ref.session.php#64525
你可能会在那里找到一些有用的建议。
https://stackoverflow.com/questions/7582485
复制相似问题