http://php.net/manual/ja/language.oop5.late-static-bindings.php
にある例2 static:: のシンプルな使用法を少しずつ変えて動きを見てみる。
①
<?php declare(strict_types=1); ini_set( 'display_errors', '1' ); error_reporting(E_ALL); class A { public function who() { echo __CLASS__; } public function test() { static::who(); // これで、遅延静的束縛が行われます //$this->who(); } } class B extends A { public function who() { echo __CLASS__; } } //B::test(); $b=new B; $b->test(); //結果: B
特に問題なし。
②
<?php declare(strict_types=1); ini_set( 'display_errors', '1' ); error_reporting(E_ALL); class A { public function who() { echo __CLASS__; } public function test() { //static::who(); // これで、遅延静的束縛が行われます $this->who(); } } class B extends A { public function who() { echo __CLASS__; } } //B::test(); $b=new B; $b->test(); //結果: B
これも特に問題なし。
③
<?php declare(strict_types=1); ini_set( 'display_errors', '1' ); error_reporting(E_ALL); class A { public function who() { echo __CLASS__; } public function test() { static::who(); // これで、遅延静的束縛が行われます //$this->who(); } } class B extends A { public function who() { echo __CLASS__; } } B::test(); $b=new B; //$b->test(); //Deprecated: Non-static method A::test() should not be called statically in C:\xampp\htdocs\Foo\Foooo.php on line 24 //Deprecated: Non-static method B::who() should not be called statically in C:\xampp\htdocs\Foo\Foooo.php on line 14 //B
非静的メソッドを静的に呼び出しているのでE_DEPRECATEDが出ている。しかしエラーではないので結果は出ている(B)
④
<?php declare(strict_types=1); ini_set( 'display_errors', '1' ); error_reporting(E_ALL); class A { public function who() { echo __CLASS__; } public function test() { //static::who(); // これで、遅延静的束縛が行われます $this->who(); } } class B extends A { public function who() { echo __CLASS__; } } B::test(); $b=new B; //$b->test(); //Deprecated: Non-static method A::test() should not be called statically in C:\xampp\htdocs\Foo\Foooo.php on line 24 //Fatal error: Uncaught Error: Using $this when not in object context in C:\xampp\htdocs\Foo\Foooo.php:15 Stack trace: #0 C:\xampp\htdocs\Foo\Foooo.php(24): A::test() #1 {main} thrown in C:\xampp\htdocs\Foo\Foooo.php on line 15
B::test();でAのインスタンスメソッドtest()が呼ばれるのでE_DEPRECATEDが出るのは③と同じ。
動的なメソッドを静的に呼び出すこと自体はできる(メソッド中に$thisがない場合)
メソッド中に$thisがあると↑のようにエラー発生。
「Using $this when not in object context in」でググった結果
http://blog.livedoor.jp/kmiwa_project/archives/1064171380.html
に該当する記事があった。↑の③なら動くよ、ということね。