- 2007-11-17 (土) 4:00
- PHP
年内のPHP4サポート終了に向けて、PHP5への移行が進む昨今です。
PHP5で推奨されていないスクリプトをチェックするのがE_STRICTです。E_STRICTが有効なのは分かっていたのですが、実際にどんなスクリプトがE_STRICTに引っかかるのかが、あやふやでした。
そこでE_STRICTで出力されるメッセージをPHPのソースから抜き出してみました。どのようなスクリプトがE_STRICTに引っかかるのか(引っかからないか)のヒントになればと思います。
ちなみにE_STRICTの活用方法としてマニュアルには[-l]オプションによるチェックが書かれていますが、スクリプトを実行しないと発生しないE_STRICTもあるので、実際には実行して確認する方が良いです。
1. Accessing static property %s::$%s as non static
インスタンス変数をクラス変数としてアクセスしている。
クラス変数としてアクセスするなら宣言時にstaticを付けます。
なお再現させようとするとE_STRICTの前に「Fatal Error:Access to undeclared static property」が発生しました。
2. Assigning the return value of new by reference is deprecated
new演算子の戻り値を参照で受け取ろうとする。
PHP5では[=]で参照渡しとなるのでインスタンス化したオブジェクトを[=&]で受け取る必要はありません。
3. Creating default object from empty value
空の値からデフォルトオブジェクトを作ろうとしている。
null or 空文字 or 未定義のインスタンス変数をオブジェクトと見なして、さらに->でそのインスタンス変数を参照しようとすると発生します。分かりにくいので↓ソースです。
<?php class Hoge { public $a = null; } $obj = new Hoge(); $obj->a->b = 1; // E_STRICT ?>
4. Declaration of %s::%s() should be compatible with that of %s::%s()
継承によりメソッドをオーバーライドする場合は、継承元と同じメソッド定義にする。
- 親クラスと引数の数が異なるとNG
- デフォルト値のあり・なしが異なるとNG(値は変わってもOK)
- Typehintも同じでないとNG
5. Function %s%s%s() is deprecated
関数XXXは非推奨。ソースをgrepした中ではdl()が非推奨となっていました。
6. Implicit cloning object of class ‘%s’ because of ‘zend.ze1_compatibility_mode’
zend.ze1_compatibility_mode=on設定時のみ発生。
オブジェクトを参照するとひたすら発生しました。zend.ze1_compatibility_mode=onにする時はE_STRICTは切った方が吉です。。。
7. Non-static method %s::%s() cannot be called statically
1.のメソッド版。クラスメソッドとして呼ぶなら、メソッド定義時にstaticを付ける。
似たメッセージとして以下のようなものがあります。
- Non-static method %s::%s() cannot be called statically, assuming $this from compatible context %s
- Non-static method %s::%s() should not be called statically, assuming $this from incompatible context
8. Only variables should be assigned by reference
メソッドの戻り値を[=&]で受け取ろうとすると発生。[=]で受け取ればokです。
似たメッセージとして以下のようなものがあります。
- Only variables should be passed by reference
9. Redefining already defined constructor for class %s
PHP4版コンストラクタ(クラス名と同じメソッド)とPHP5版コンストラクタ(__construct)が定義されている。
できればコンストラクタは__constructにします。PHP4のソースをそのまま使用するなら__constructを記述しないようにします。
10. Resource ID#%ld used as offset, casting to integer (%ld)
リソースIDを連想配列のインデックスとして使用すると発生します。
実際のシステムで発生するシチュエーションが良く分からないのですが、以下のソースでは確かに発生します。
<?php $fp = fopen("hoge", "r"); $array = array(1 => "a", 2 => "b"); var_dump($array[$fp]); ?>
11. Static function %s%s%s() should not be abstract
クラスメソッドはabstractにしない。
クラスメソッドにしたところでabstractだと呼びようがありません。
12. Usage of {} to access string offsets is deprecated and will be removed in PHP 6
{}による文字列へのアクセスはPHP6で消えるので非推奨です。マニュアルでは[]でのアクセスを推奨しています。
ただこのメッセージはソースには含まれていますが、「#ifdef 0_ilia」となっているので、通常のbuildでは表示されません。(以後のリリースで有効化?)
13. is_a(): Deprecated. Please use the instanceof operator
is_a()は非推奨。代わりにinstanceofを使います。
<?php class Hoge { } class Bar extends Hoge { } $obj = new Hoge(); var_dump(is_a($obj, 'Hoge')); // E_STRICT var_dump($obj instanceof Hoge); // ok ?>
14. It is not safe to rely on the system’s timezone settings …
タイムゾーンの明示的な設定をせよ。デフォルトセッティングをあてにしてはいけない。
全文は以下な感じです。
It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Tokyo' for '9.0/no DST' instead in
環境変数で設定するか、date_default_timezone_set(‘Asia/Tokyo’)で設定しておけばokです。
これからはE_STRICT対応で?
以前はvarでインスタンス変数を定義しただけでE_STRICTが発生していたため、PHP4のソースを移行する際は正直あまり使っていませんでした。ただ5.1.3でこの処理は削除されていますので、PHP4なソースでも使ってみようと思います。
早速PHP5で動作しているPHP4なソースをE_ALL|E_STRICTで実行してみると7.関連でエラーが多数出てきました。。。うーん、これ全部直すのか。。。
コメント (Close):2
- yando 07-11-17 (土) 5:03
-
おー。
全く同じ資料を業務で作りました。parserでやってるやつとそうでないやつがあるんですよね。
ただこれだとエラーメッセージレベルなのでメッセージ次第なんですよねー。 - shinbara 07-11-17 (土) 11:28
-
> 全く同じ資料を業務で作りました。
あちこちで作ってそうですね。;-)gophp5な情報は皆で共有したいですよね。
> parserでやってるやつとそうでないやつがあるんですよね。
E_STRICT出ないのでも、挙動が代わってる箇所が
あるので(オブジェクト参照とか)
結局は実行しながら修正して行くんですけどね。;-)
トラックバック:9
- このエントリーのトラックバックURL
- /blog/2007/11/php_e_strict_message.html/trackback
- Listed below are links to weblogs that reference
- PHP E_STRICTで表示されるエラーメッセージを調べてみた from Shin x blog
- pingback from 楽人 » XAMPPでPostgresqlとphpPgAdmin 10-04-25 (日) 23:55
-
[…] http://www.1×1.jp/blog/2007/11/php_e_strict_message.html new演算子の戻り値を参照で受け取ろうとする。 PHP5では[=]で参照渡しとなるのでインスタンス化したオブジェクトを[=&]で受け取る必要はありません。 […]
- pingback from PHPのエラーハンドラを使うときに覚悟するべきこと | Hoge2rock 10-05-18 (火) 1:21
-
[…] さらに、E_STRICTを防ごうとするのはもっと大変です。 どういう時にE_STRICTレベルのエラーが出るかは「PHP E_STRICTで表示されるエラーメッセージを調べてみた」に詳しいのですが、代表的なのはstatic修飾子がついてないメソッドを静的にコールしたり、PHP4形式のコンストラクタとPHP5形式のコンストラクタの両方が宣言されていたりというものです。 これらはPHP4の上でもPHP5の上でも動くスクリプトを書こうとすると避けることが出来ません。 つまり、E_STRICTが出ないコードを書こうとするとPHP5の上でしか動かないスクリプトになってしまいます。 CakePHPを含む多くのPHPフレームワークはPHP4とPHP5の両方で動くように作られている為、これらのフレームワークを使うと大量のE_STRICTが出ます。 […]
- pingback from dfgallery PHP5.3での修正 10-11-25 (木) 19:02
-
[…] php5は=で参照渡し ここを参照 […]
- pingback from CakePHP : CakePHP1.2 を PHP5.3 で動かした際に出たエラーの対処方法 | ゆる~くWebのこと 11-12-28 (水) 19:12
-
[…] PHP E_STRICTで表示されるエラーメッセージを調べてみた | Shin x blog […]
- pingback from pc.casey.jp » [CakePHP][BaserCMS] PHP5.3 でエラー 12-05-25 (金) 22:30
-
[…] その他の変更内容やエラーとその対処については「PHP E_STRICTで表示されるエラーメッセージを調べてみた – Shin x blog」が詳しい。 […]
- pingback from php 5.2.x から 5.3へ移行 | mly520 13-02-13 (水) 20:52
-
[…] php5は=で参照渡し ここを参照 […]
- pingback from Zend_Gdata – Strict Standards: Declaration of Zend_Gdata::import() | deadwood 13-06-13 (木) 21:03
-
[…] PHP E_STRICTで表示されるエラーメッセージを調べてみた – Shin x blog […]
- pingback from [CakePHP]Xformjpで継承エラー | YONEZO-NET 14-03-04 (火) 13:24
-
[…] 参考:PHP E_STRICTで表示されるエラーメッセージを調べてみた […]
- pingback from 無計画算法 | Ubuntu14.04LTSにMindTouch Deki Wikiを立てる 15-02-02 (月) 9:05
-
[…] http://www.1×1.jp/blog/2007/11/php_e_strict_message.html […]