非同期といっても、イベントを投げるだけなので、
非同期で行った結果を取得できないので、使いどころは少ないという。。
まあ一応こんなやり方もできましたってことで。
やり方としてはキックする側とキックされる側を少し弄ればOK
キックする側
こんな感じの関数を書いてみました。
単純にURIにアクセスして、fgetせずに即コネクションを落とすというだけ。
function async_access($uri){ if ($parsed = parse_url($uri)) { $host = $parsed['host']; $path = ($parsed['query'])?$parsed['path'].'?'.$parsed['query']:$parsed['path']; if (isset($host) && isset($path)) { $fp = fsockopen($host,80,$errNumber,$errMessage,3); if ($fp) { $request = "GET {$path} HTTP/1.1\r\n"; $request .= "Host: {$host}\r\n"; $request .= "Connection: close\r\n\r\n"; fputs($fp,$request); fclose($fp); return true; } } } return false; }
ただ普通にやるとこれだけだと、キックされる側によって、
PHPが最後まで実行される or されない というのが変わってしまうので、
キックされる側のPHPをチェックします。
キックされる側
ここらへんPHPの接続処理関係
をみればわかるように、PHPのステータスは3つあるわけですが、
今回のように即コネクションを閉じてしまうと基本的にはABORTEDになるわけです。
で、このABORTEDになったときにPHPの処理をとめるorとめないというのを制御してあげれば
上の関数でキックしたあと、きちんと処理をして終わってくれるというわけです。
で、調べた限りでPHPが最後まで実行してくれるようにするには2パターンありました。
●1個目
PHP側で一切出力処理をしない。
⇒単純にheader()とか echo,print などを削除&バッファ関連の ob_~ も削除する。
●2個目
どうしてもprintなどの処理が必要な場合は
ignore_user_abort(true)を最初にかき、 ob_startにてバッファ処理をさせて、
出力時は ob_flush() などで対応する。
これのどちらかをやれば問題なく動きました。
まあいずれにせよ、キックされた側のPHPの終了を読み取るには register_shutdown_function などを使って
再度こっちにキックしなおさないといけなかったりするので、
基本的には片道切符として使ったほうがいいと思います。
参考文献
ignore_user_abort(false)でPHPが処理を中断しない件
ignore_user_abort=falseなのにスクリプトが止まらない
ignore_user_abort
PHPの接続処理関係