検証事項
- 親クラスと子クラスではどちらが先に定義されるか
- 親クラスで読み込んだトレイトと子クラスで読み込んだトレイトではどちらが先に定義されるか
- 同一クラス内で先に読み込んだトレイトとあとに読み込んだトレイトではどちらが先に定義されるか
検証コード
<?php
trait Ta { function a() {} }
trait Tb { function b() {} }
trait Tc { function c() {} }
class Foo
{
use Ta;
function hoge() {}
}
class Bar extends Foo
{
use Tc;
function fuga() {}
use Tb;
function piyo() {}
}
$obj = new Bar();
var_dump(PHP_VERSION);
var_dump(get_class_methods($obj));
実行結果
% php test.php
string(17) "5.4.15-1~dotdeb.2"
array(6) {
[0] =>
string(4) "fuga"
[1] =>
string(4) "piyo"
[2] =>
string(4) "hoge"
[3] =>
string(1) "a"
[4] =>
string(1) "c"
[5] =>
string(1) "b"
}
結論
(前提: 少なくとも PHP 5.4.15 では)
- 子クラスのメソッドの方が、親クラスのメソッドよりも先に定義される
- クラスに直接定義したメソッドの方が、トレイトで読み込んだメソッドよりも先に定義される
- 親クラスで読み込んだトレイトのメソッドの方が、子クラスで読み込んだトレイトのメソッドよりも先に定義される
- 上部に書いたメソッドの方が、下部に書いたメソッドよりも先に定義される
パターンに一致するメソッドをすべて実行するようにして、トレイトを読み込むだけで実行時の挙動を拡張できるような実装を考えたんだけど、読み込む順番どうなるんだろうと思って検証してみました。
結果的に、順番を考慮しなきゃならないならそういうことはやっちゃいけなさそうな感じがしました。