7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

php static変数の継承の注意

Posted at

phpでクラスの継承を利用しているとき、親クラスのstatic変数が子クラスでどう扱われるかというポイントで嵌ったので公開する。
理屈がわかってしまえば当たり前の動きなのだが、インスタンス変数の感覚でいたため痛い目にあってしまった。

継承関係にある次のクラスを作成する。

class A{
    public static $a = 'a';
}

class B extends A{
    public static function init(){
        self::$a = 'b';
    }
}

class C extends A{
    public static function init(){
        self::$a = 'c';
    }
}

ここで次の処理はさすがに自明な結果を返す。

echo A::$a . "\n"; // > a
echo B::$a . "\n"; // > a
echo C::$a . "\n"; // > a

ここで次の魔法をかける。

B::init();

するとさきほどの結果は次のように変化する。

echo A::$a . "\n"; // > b
echo B::$a . "\n"; // > b
echo C::$a . "\n"; // > b

つまり、自身のstaticプロパティを書き換えたつもりでも、親も兄弟もすべて書き換えてしまったかのような結果となる。
上のように明確な定義をしていれば、まあなんでもない挙動だが、もともと親になかったstaticプロパティが
ある日突然親に追加された瞬間、地獄を見る。

ちなみに、class Bでstatic変数を再定義しておけば、上記のような現象は回避される。

class B extends A{
    public static $a = 'a';
    public static function init(){
        self::$a = 'b';
    }
}
B::init();
echo A::$a . "\n"; // > a
echo B::$a . "\n"; // > b
echo C::$a . "\n"; // > a
7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?