説明
PHPで、未定義変数またはnull
を持つ変数のメンバにアクセスするコードを実行すると、そのメンバがプロパティかメソッドかでエラーのレベルが異なります。
- プロパティ(メンバ変数)へのアクセス: Notice (
E_NOTICE
) - メソッド(メンバ関数)へのアクセス: Fatal error (
E_ERROR
)
これらのレベルの違うエラーがレポートされるかどうかは、error_reporting
の設定によります。
そしてプログラムの制御に関しては次の違いがあります。
-
E_NOTICE
: 中断しない -
E_ERROR
: 中断
背景
私は先日あるバグを調べているときに、
- ある変数のプロパティにアクセスする部分を無事に通過し
- その後のメソッド呼び出しで
Fatal error
になっている
という現象に遭遇し、なぜプロパティへのアクセスの時点でエラーにならないのか、理解できませんでした。いろいろと調べた結果、エラーレベルの違いによるということが判明しました。
実験1
sample.php
<?php
error_reporting(E_ALL & ~E_NOTICE);
$a = null; // この行がなくても同じ
echo '[', $a->someProperty, "]\n"; // レポートされない
echo '[', $a->someMethod(), "]\n"; // エラーで中断
結果
[]
[PHP Fatal error: Call to a member function someMethod() on a non-object in /Users/wada/sample.php on line 6
実験2
sample2.php
<?php
error_reporting(E_ALL);
$a = null; // この行がなくても同じ
echo '[', $a->someProperty, "]\n"; // レポートされるが継続
echo '[', $a->someMethod(), "]\n"; // エラーで中断
結果
[PHP Notice: Trying to get property of non-object in /Users/wada/sample2.php on line 5
]
[PHP Fatal error: Call to a member function someMethod() on a non-object in /Users/wada/sample2.php on line 6