node.js などの言語は、非同期データベース クエリ関数を実装できます。SQL ステートメントの実行後にデータベースが結果を返すのを待つ必要はありません。他のコードの実行を続けて、データベースが結果を返すと、ページのレンダリングやクライアントへの HTML ページの送信などのデータが処理されます。このようにして、アプリケーションはブロックしたり待機したりする必要がまったくありません。この方法は非常に効率的に機能します。
同様の非同期ノンブロッキング MySQL クエリを PHP で実装することは可能ですか? github を使用して、この機能を実行していると思われるプロジェクトを検索します (https://github.com/kaja47/async-mysql)。コードは React.PHP に基づいています。しかし、実際には非同期 SQL ではありません。実装の原則は、タイマーを設定して 0.02 秒ごとにポーリングすることです。使用することはできますが、CPU リソースの無駄になります。実際には非同期の MYSQL ではありません。
現在、Swoole1.6.2 では、真の PHP 非同期 MySQL を実現するために使用できる 2 つの新しい関数、swoole_event_add と swoole_get_mysqli_sock を提供しています。具体的な実装について話しましょう。
コード:
$db = new mysqli;
$db->connect('127.0.0.1', 'root', 'root', 'test'); ", MYSQLI_ASYNC);
swoole_event_add(swoole_get_mysqli_sock($db), function($db_sock) {
global $db;
$res = $db->reap_async_query();
var_dump($res->fetch_all(MYSQLI_ ASSOC) ));
swoole_event_exit();
});
まず接続が成功したら、SQL ステートメントを実行し、2 番目のパラメーターに MYSQLI_ASYNC を指定します。このクエリが非同期であることを示します。クエリ関数はすぐに戻りますが、この時点では mysqli_result は取得されません。
次に、swoole_get_mysqli_sock 関数を呼び出して mysql 接続のソケットを取得し、swoole_event_add を呼び出してそれを swoole の epoll イベント ループに追加します。データベースが結果を返すと、作成したばかりの関数がコールバックされます。
このとき、mysqli_reap_async_queryを呼び出して結果を取得し、fetch_all関数を呼び出してデータを取得します。
このプロセスは完全に非同期でノンブロッキングであり、CPU を浪費するコードはありません。このコードはサーバー側プログラムでも使用できます。具体的なコードの実装については、後の記事で詳しく説明します。