11

PHPMySQLiを介して非同期クエリを使用しようとしています。

次のコードは簡略化されています。元のコードは冗長すぎて、クラスの依存関係などのためにここにリストできません。また、接続への参照mysqli_handleはすでに設定されていると想定してください。

$query_1 = "SHOW TABLES FROM moxedo";
$query_2 = "CREATE TABLE `moxedo`.`mox_config_n85ad3` (`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT , `group_id` INT(3) UNSIGNED NOT NULL , `is_enabled` INT(1) UNSIGNED NOT NULL , `tag` VARCHAR(255) NOT NULL , `name` VARCHAR(80) NOT NULL , `value` VARCHAR(255) NOT NULL , `description` TEXT NOT NULL , `init_params` TEXT NOT NULL , `datetime_added` DATETIME NOT NULL , `datetime_lastmodified` DATETIME NOT NULL , `timestamp_univ` BIGINT(14) NOT NULL , PRIMARY KEY ( `id` ) ) ENGINE = INNODB
";
$query_3 = "ALTER TABLE `moxedo`.`mox_config_n85ad3` ADD UNIQUE `ix_u_tag_oq` ( `tag` )";
$query_4 = "SHOW TABLES FROM moxedo";

if (!$mysqli_stmt_obj = $mysqli_handle->query($query_1)) 
{
   printf("Error: %s\n", $mysqli_handle->error);
}

if (!$mysqli_stmt_obj = $mysqli_handle->query($query_2, MYSQLI_ASYNC)) 
{
   printf("Error: %s\n", $mysqli_handle->error);
}

if (!$mysqli_stmt_obj = $mysqli_handle->query($query_3, MYSQLI_ASYNC)) 
{
   printf("Error: %s\n", $mysqli_handle->error);
}

if (!$mysqli_stmt_obj = $mysqli_handle->query($query_4)) 
{
   printf("Error: %s\n", $mysqli_handle->error);
}

クエリ1の呼び出しはOKを通過します。クエリ2の呼び出しもOKを通過します。

ただし、クエリ3とクエリ4を実行しようとすると、「コマンドが同期していません。このコマンドを今すぐ実行できません」というエラーが表示されます。オンラインで調べたところmysqli_free_result、クエリ2とクエリ3の使用に関する情報が見つかりましたが、結果セットはありません。

このエラーが発生せずに複数の呼び出しを行えるように、非同期呼び出しを適切に終了するにはどうすればよいですか?

4

1 に答える 1

20

残念ながら、特にこの点に関して、mysqli のドキュメントはかなり不足しています。問題は、「非同期」モードが mysql クライアント側の動作であり、クライアント/サーバー プロトコルの一部ではないことです。つまり、特定の時間に 1 つの接続で実行できるクエリは 1 つだけ (または複数のクエリだと思います) です。MYSQLI_ASYNCクエリ結果の待機中にアプリケーションがブロックされないように指定するだけです。結果は後で で収集する必要がありmysqli_poll()ます。

あなたの例で$query_1は、同期しているため、返されてに割り当てられるまでに完全に完了します$mysqli_stmt_obj$query_2正常に非同期に開始さ$mysqli_handleれ、結果を待たずに戻ります。スクリプトが に到達するまで$query_3に、まだ を待っている保留中の結果があり$query_2ます。したがって、最後のクエリを終了する前に別のクエリを送信しようとするため、「コマンドが同期していません」。

于 2013-10-21T12:38:24.000 に答える