ob_start、register_shutdown_function あたり挙動がPHP4、PHP5で異なる。
rhacoのSnapshotのバグを調査してて、PHP4とPHP5での動きの違いがあったので、純粋なPHPのみで検証してみた。
結論その1
ob_startした後、Fatal error を意図的に発生させています。Fatal error が発生すると、shutdown関数がCallされて、その中でob_get_contents&ob_get_cleanしています。
- PHP4
- 'Fatal error: ...' は自動で表示される。
- ob_get_contentsで''が返ってくる。
- PHP5
- 'Fatal error: ...' は表示されない。
- ob_get_contentsで'Fatal error: ...'が返ってくる。
検証に使ったスクリプト
<?php echo phpversion() . "<br/>\n"; function shutdown(){ $buf = ob_get_contents(); ob_get_clean(); echo "<table border='1'><tr><td>\n"; print_r($buf); echo "</td></tr></table>\n"; echo "shutdown.<br/>\n"; exit; } register_shutdown_function("shutdown"); ob_start(); echo "contents<br/>"; xxx(); // Fatal error $buf = ob_get_contents(); ob_get_clean(); echo $buf; echo "finish.<br/>"; ?>
結論その2
さらに、PHP5の場合、shutdownの中で ob_get_cleanしたり、しなかったりで挙動が変わった。なんか不思議な動きなんだけど。
- PHP4
- Fatal発生→バッファを吐き出し→shutdown関数Call
- PHP5
- shutdown関数の中でob_get_cleanしている場合、Fatal発生→shutdown関数Call
- shutdown関数の中でob_get_cleanしていない場合、Fatal発生→バッファ吐き出し→shutdown関数Call
ようは、PHP5でshutdown関数の中でog_get_cleanしてしまうと、Fatal error が表示されなくなってしまう。
こんな感じに見える。