Edited at

PHP7の構文解析プロセスが刷新されたことが一目でわかるエラー表示

More than 3 years have passed since last update.

PHP5とPHP7では構文解析、つまり、テキストファイルからPHPで書かれたソースコードを読み込んでインタプリタで実行するまでのプロセスに変更がありました。PHPの実行時とコンパイル時に書いたのですが、PHPは実行ごとにソースコードから仮想機械(Zend VM)のバイトコード(opcode)にコンパイルされます1

とは言っててもふつうにPHPを書いてる限りではあまり実感する差分ではないのですが、PHP5.6で動かしながらコードを書いてたら、「おやっ」と感じる挙動を発見し、この短いコードでPHPの構文解析の変更について説明できることに気がついたので紹介します ><

<?php

class Hoge
{
function foo()
{
}

/**
* メソッド定義を追加しようとしてうっかり既存のメソッドと同じ名前で、
* 実装する前にセーブした状態で実行しちゃったケースを想像
*/

function foo

public function buz()
{
}
}


php7

PHP Parse error:  syntax error, unexpected 'public' (T_PUBLIC), expecting '(' in /home/jail/prog.php on line 15



php5.6

PHP Fatal error:  Cannot redeclare Hoge::foo() in /home/jail/prog.php on line 13


次に、function foofunction barに置換、つまりメソッド名の重複は起こらないようにしてみます。


php5.6

PHP Parse error:  syntax error, unexpected 'public' (T_PUBLIC), expecting '(' in /home/jail/prog.php on line 15


この差分をコンパイラの気持ちになってみると、PHP5時代はソースコードのパースをしながら順次メソッドの定義もやってたんですねー、だからその後の実装部分のsyntax errorを検出する前にメソッド名の重複を検査できたんですねー。

ここで重複定義のチェックができても誰が得するんだって感じなのでPHP7の挙動の方が自然だと思ひます。





  1. @hnwZend OPcacheの速さの秘密を探るにまるっと説明されてるので、お読みください