PHPのライブラリの継承ラッパーを作っていて認識違いでハマったのでメモ。
状況
例えばこんなライブラリがあり。
基本的にはライブラリ内のコードには手を出したくないので、ここには調整は入れませんが、
デフォルトで $hensuu という変数が存在(ここでは宣言のみ)しています。
class Library_sample {
var $hensuu;
public function test(){
//なんやかんや
}
}
で、それを継承するラッパークラスを作りました。
class Hoge extends Library_sample{
public $hensuu = true;
public $hensuu2 = true;
public function __construct()
{
parent::__construct();
}
このラッパークラス「Hoge」で変数、$hensuuにtrueをセットしています。
ついでに$hensuu2も作り、こちらにもtrueをセットしています。
で、このラッパークラスのインスタンスを作り、そのインスタンスからhensuuを表示しようとすると、、、なぜかfalseとなっておりました。
でも、同じ場所でtrueを入れているhensuu2の方はtrueが出力されています。。
$hoge = new Hoge;
echo $hoge->hensuu; // false
echo $hoge->hensuu2; // true
※各ファイルのincludeなどは省略しております。
これは一体。。?!
あれ?コンストラクタってインスタンス作る時に最初に実行されるから、ほんで継承してるから
「Hoge.php」のparent::__construct(); のところでまずは変数宣言→
その後に
hensuu = true;
hensuu2 = true;が行われたのでは。。。?としばらくはてながっていました。
結論:単純に順序逆だった
「Hoge.php」の中のpublic変数として先に宣言された後に、コンストラクタが実行されてたみたいです。
hennsuu1はtrueになり、コンストラクタの中で親クラスで改めて宣言されたことでただの変数=falseになった。
hennsuu2はtrueになり、コンストラクタの中で親クラスで、、、は特に宣言されていないのでそのまま変数=trueだった。
ということです。
ここ、勘違いしていました。
では
どうすべきかというと、子供のHoge.php側の「コンストラクタの中でtrueにするべき」でした。
という学びでした。
この辺の順序、思い込みをしていたのでどこでこの挙動になっているんだ?と少しコードを細かくおったりしてました。。w