この拡張モジュールは、非同期 POSIX I/O 機能を提供します。 Marc Lehmann による » libeio C ライブラリを利用します。
注意:
この拡張モジュールは Windows環境では利用できません。
警告 注意すべき点は、個々のリクエストが単一のスレッド内で実行され、 キューに入れた一連のリクエストの実行順は基本的に不定であるということです。 たとえば、次のコード片は間違っています。
例1 間違ったリクエスト
<?php// $filename のシンボリックリンクを $link に作るリクエストeio_symlink($filename, $link);// $filename を $new_filename に移動するリクエストeio_rename($filename, $new_filename);// リクエストを処理しますeio_event_loop();?>
この書き方だと、eio_rename() のほうが eio_symlink() よりも先に処理されてしまう可能性があります。 そうならないようにするには、eio_rename() を eio_symlink() のコールバックの中から呼びます。
例2 リクエストコールバックからのリクエストの呼び出し
<?phpfunction my_symlink_done($filename, $result) { // $filename を $new_filename に移動するリクエスト eio_rename($filename, "/path/to/new-name"); // リクエストを処理します eio_event_loop();}// $filename のシンボリックリンクを $link に作るリクエストeio_symlink($filename, $link, EIO_PRI_DEFAULT, "my_symlink_done", $filename);// リクエストを処理しますeio_event_loop();?>
あるいは、リクエストグループを作るという手もあります。
例3 リクエストコールバックからのリクエストの呼び出し
<?php/* これは、グループリクエストが終わってから呼ばれます */function my_grp_done($data, $result) { // ...}function my_symlink_done($filename, $result) { // eio_rename リクエストを作り、グループに追加します $req = eio_rename($filename, "/path/to/new-name"); eio_grp_add($grp, $req); // もっとリクエストを追加したければ、ここで追加します}// リクエストグループを作ります$grp = eio_grp("my_grp_done", "my_grp_data");// eio_symlink リクエストを作り、グループに追加します// $filename をコールバックに渡します$req = eio_symlink($filename, $link, EIO_PRI_DEFAULT, "my_symlink_done", $filename);eio_grp_add($grp, $req);// リクエストを処理しますeio_event_loop();?>
グループとは特殊な形式のリクエストのことで、通常の eio リクエストを複数積み上げることができます。 これを使えば、ファイルを開いて読み込んでから閉じるといった 複雑なリクエストを作れます。 バージョン 0.3.0 alpha 以降では、 libeio との通信で内部的に使う変数を eio_get_event_stream() で取得できます。 この変数を使うと、他の拡張モジュールでサポートしている イベントループにバインドできます。 シンプルなイベントループを作って、eio と libevent を一緒に動かしたりできるのです。
例4 eio と libevent を組み合わせる例
<?phpfunction my_eio_poll($fd, $events, $arg) { /* libevent の設定があればここに書きます .. */ if (eio_nreqs()) { eio_poll(); } /* .. そしてここにも書きます */}function my_res_cb($d, $r) { var_dump($r); var_dump($d);}$base = event_base_new();$event = event_new();// このストリームを使って libevent にバインドします$fd = eio_get_event_stream();eio_nop(EIO_PRI_DEFAULT, "my_res_cb", "nop data");eio_mkdir("/tmp/abc-eio-temp", 0750, EIO_PRI_DEFAULT, "my_res_cb", "mkdir data");/* その他の eio_* コール ... */// イベントフラグを設定しますevent_set($event, $fd, EV_READ /*| EV_PERSIST*/, "my_eio_poll", array($event, $base));// イベントベースを設定しますevent_base_set($event, $base);// イベントを有効化しますevent_add($event);// イベントループを開始しますevent_base_loop($base);/* バッファつき libevent インターフェイスでも同様にできます */?>