既存の関数をクロージャ化する関数を追加しました。
string co_enclose(callback $func[, array $env_vars[, int $flags]])
これは co_make_callable(co_create($func, $env_vars, $flags))
を短く書けるようにしたものです。
引数の詳しい説明は一昨日のエントリの co_create() および定数の項を参照してください。
これを使ってコルーチンもどきを作ってみましょう。
コード:
<?php function pseudo_coro_impl() { switch (++$coro_state) { case 1: var_dump($param1, $param2); return; case 2: $str = str_repeat($param1, $param2); return; case 3: var_dump($str); return; } } function pseudo_coro_init($param1, $param2) { $coro_state = 0; return co_enclose('pseudo_coro_impl', null, CONTINUATION_ALL); } $coro1 = pseudo_coro_init('foo', 6); $coro2 = pseudo_coro_init('bar', 2); $coro1(); $coro2(); $coro1(); $coro2(); $coro1(); $coro2();
結果:
string(3) "foo" int(6) string(3) "bar" int(2) string(18) "foofoofoofoofoofoo" string(6) "barbar"
状態管理に自前で $coro_state をインクリメントしているのが不細工なのは置いといて、ちゃんと return したときのローカル変数の値が $coro1 と $coro2 で個別に保持されていますね。
continuation モジュールを使うと PHP のスコープではできなかったことができるようになります。