PHP 5.1.0beta-RC あたりで Mac OS X では make test では必ず fail して「何じゃこりゃ」と思っていた __halt_compiler()
関数を試してみた。
ストリーム関数の勉強も兼ねたサンプルコード:
<?php // php halt_compiler.php -m 0 | tee -a halt_compiler.php $fp = fopen(__FILE__, 'r'); $out = fopen('php://stdout', 'wb'); $mode = ($argc >= 3 && $argv[1] == '-m') ? (int)$argv[2] : 1; if ($mode == 0) { $params1 = array('level' => 9); $params2 = array('line-length' => 76, 'line-break-chars' => "\n"); $f1 = stream_filter_append($out, 'zlib.deflate', STREAM_FILTER_WRITE, $params1); $f2 = stream_filter_append($out, 'convert.base64-encode', STREAM_FILTER_WRITE, $params2); stream_copy_to_stream($fp, $out, __COMPILER_HALT_OFFSET__); /* stream_filter_remove($f1); stream_filter_remove($f2); */ // Unable to flush filter, not removing /* stream_filter_remove($f2); stream_filter_remove($f1); */ // base64-encode skipped fclose($out); // flush filter file_put_contents('php://stdout', "\n"); } else { fseek($fp, __COMPILER_HALT_OFFSET__); stream_filter_append($fp, 'convert.base64-decode'); if ($mode == 1) { stream_filter_append($fp, 'zlib.inflate'); var_dump(stream_get_contents($fp)); } else { $fl = stream_filter_append($out, 'zlib.inflate'); stream_copy_to_stream($fp, $out); stream_filter_remove($fl); fwrite($out, "\n"); } } __halt_compiler(); jVTbTttAEH33V4xQhG0UxyRUVCU1CFWJQAJRhVR9aNFqY48TK+tda70JoiX/3vGFyElArl+s3Tlz zlyO/fUqW2SW7wO9YMGFYaFKs0Sg7hU3Xgqn8AoGETx+GLc6cQYBxCpD6TA2vr0bMdYFW9vu0Oqo ldkGbUJf+H5uIrq1CfI8KzGpipBA4HS4nodwGcAZHB9DcVr/6j9BEIDtpbYLV+Ak0rhVYPAEF9Af WklMiRVFAKcu/LWAnk7GNU/zPvFyrfmLYwtco7AhuIQvJNrADBqYRKInUM7NokR+Pqcqy8uZRr70 wgXXeRk5+i2P3mjiQiU3hEhZnAiDmvGMGo6con1i+COSWS/CWHCD1PfjdDK6vi8mNR1N2M/J7XTU 3Ra8JR20kIZKrlGb3ozneP7JQxnSDFrYBzV7zRuq7IUZxaqjQ4skZMnO2LeH+++0ygm7ub6bsofx +HE0ZazO90/2StOYqjUSA9X/UYjE4cQH8tkPyWcCwSiIxSpfQIXsglQGSngi5y06g491+ludndFA vkxogFFJHIdC5ViOktAEbRZSIcjfLFsVXpcGpckP7FtbYAMocqxtF+eIy2qQLSN8f7VF4v5mIyw3 W+ft2L3/ZvcWxtKAiawMWBMVz5prFq3SzKlz59jol1LdGrvTY2VP8T+ef0eyxXqHyP31igYkftaJ wVqy8UlurI3F2M6vynGH/wA=
うまく使えばいろいろと面白いことができそうな予感。
しかしそれよりも zlib.deflate フィルタの挙動が気になった。
どうも flush されるまで次のフィルタにデータを渡さないようになっているっぽい。