0

重複の可能性:
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');

これは実行可能ですか?

4

3 に答える 3

2

クエリには、 ( ManualINSERT )を使用できます。これらのクエリはワークキューに配置され、すぐに返されます。欠点は、クエリが正常に実行されたかどうかに関するフィードバックがないことです。INSERT DELAYED

しかし、あいまいな理由で、UPDATE DELAYED...

于 2013-01-23T21:36:08.523 に答える
1

一般的な方法は、最初に出力をレンダリングし、次にを使用して出力をクライアントにフラッシュしflush()、次に時間消費クエリを実行することです。また、について知っておく必要がありignore_user_abort()ます。この関数は、クライアントへの接続が終了した可能性がありますが、PHPを実行し続けます。(例:ユーザーがブラウザを閉じる)

これを説明する2つのスクリプトを用意しました。1つはslow.php、出力を早期にフラッシュしてから、時間のかかるタスクを開始する方法です。2つ目は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);
于 2013-01-23T21:28:12.410 に答える
0

更新中に、ユーザーにローダーを表示する AJAX 経由で更新スクリプトを呼び出します。

ページの読み込み時に出力にクエリの結果が本当に必要ない場合は、それが唯一の方法です。

于 2013-01-23T21:26:20.430 に答える