がるの健忘録

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

関数二重定義とexitの蜜月な関係

えと…また楽しいお話が舞い込んできました。
現場からどうぞ。

<?php
dispMyMsg();
exit;// exitすると怒られない
function dispMyMsg(){
	echo "function1";
}

function dispMyMsg(){
	echo "function2";
}
?>

…すんごいですねぇ正気でしょうか?
がるがる探索班は調査を続け、そこに驚愕の事実を発見しました。


まず、exit(またはreturn)で、どうも「一端コンパイルをやめてるくさい」です。
んで。
「未定義な関数やクラスがある」場合、仕方なくコンパイルを続行。ただし「見つかった時点でコンパイルを終了」します。
こーゆーロジックですから、当然重複チェックなどいたしませぬ。


故に。以下のコード、普通に通ります。

<?php

dispMyMsg();

$obj = new foo;
$obj->dispMyMsg();

return ;

class foo {
function dispMyMsg(){ echo "function0-1 \n"; }
}

class foo {
function dispMyMsg(){ echo "function0-2 \n"; }
}

function dispMyMsg(){
        echo "function0 \n";
}


function dispMyMsg(){
        echo "function1 \n";
}

function dispMyMsg(){
        echo "function2 \n";
}

?>


んで。処理の流れ上当然なのですが「早い者勝ち」です。仁義なき戦いです。いい加減真っ当なLintくらい欲しいものです。
ちなみにPHP5系では発生しません。少なくとも5.0.4以降では発生しないことを確認しました。


…余談ですが。
PHP4.3.10で

Content-type: text/html
X-Powered-By: PHP/4.3.10

function0

って出力なのが、4.3.11で

function0

ってどうなんでしょう? メンテナンスバージョンが一つ違うだけですよねぇ? ねぇ? ねぇ?
…バッチ組んでた人の苦労がしのばれそうである。


「関数を組んだはずなのになぜかcallされない」とお嘆きのあなた。
もしかするとそれは、exitとの蜜月な浮気モノが邪魔をしているのかもしれませんよ?