PHP5とPHP7では構文解析、つまり、テキストファイルからPHPで書かれたソースコードを読み込んでインタプリタで実行するまでのプロセスに変更がありました。PHPの実行時とコンパイル時に書いたのですが、PHPは実行ごとにソースコードから仮想機械(Zend VM)のバイトコード(opcode)にコンパイルされます1。
とは言っててもふつうにPHPを書いてる限りではあまり実感する差分ではないのですが、PHP5.6で動かしながらコードを書いてたら、「おやっ」と感じる挙動を発見し、この短いコードでPHPの構文解析の変更について説明できることに気がついたので紹介します ><
<?php
class Hoge
{
function foo()
{
}
/**
* メソッド定義を追加しようとしてうっかり既存のメソッドと同じ名前で、
* 実装する前にセーブした状態で実行しちゃったケースを想像
*/
function foo
public function buz()
{
}
}
PHP Parse error: syntax error, unexpected 'public' (T_PUBLIC), expecting '(' in /home/jail/prog.php on line 15
PHP Fatal error: Cannot redeclare Hoge::foo() in /home/jail/prog.php on line 13
次に、function foo
をfunction bar
に置換、つまりメソッド名の重複は起こらないようにしてみます。
PHP Parse error: syntax error, unexpected 'public' (T_PUBLIC), expecting '(' in /home/jail/prog.php on line 15
この差分をコンパイラの気持ちになってみると、PHP5時代はソースコードのパースをしながら順次メソッドの定義もやってたんですねー、だからその後の実装部分のsyntax errorを検出する前にメソッド名の重複を検査できたんですねー。
ここで重複定義のチェックができても誰が得するんだって感じなのでPHP7の挙動の方が自然だと思ひます。
-
@hnwのZend OPcacheの速さの秘密を探るにまるっと説明されてるので、お読みください ↩