注目キーワード
  1. npm
  2. composer
  3. css

[PHP] staticフィールドは安易に使わないほうが良い説

PHPのstaticフィールドには、私の目には奇妙としか思えない挙動があるようです。見事に嵌ったので、反省と自戒を兼ねて書きます。

概要

親クラス側でstaticフィールドを用意した場合、直近に利用した子クラスの影響を、親クラスと兄弟クラスの全てが受けます。

つまり、子クラスごとにフィールドが用意されるのではなく、親クラス側で用意されているようです。

具体的なサンプルコードを見てみましょう。

サンプルコード

<?php

class Base {
	protected static $message;
	
	function say() {
		if(is_null(static::$message)) {
			static::$message = sprintf('Hello %s', get_class(new static()));
		}
		
		printf('%s\n', static::$message);
	}
}

class A extends Base {
	function bye() {
		static::$message = sprintf('Bye %s', get_class(new static()));
		printf("%s\n", static::$message);
	}
}

class B extends Base {
}

$a = new A();
$b = new B();

$a->say();
$a->say();
$b->say();
$b->say();
$a->bye();
$b->say();

解説

なんらかの計算結果をstaticフィールドに保持して使いまわしたいことはあると思います。

上記のコードで期待する出力は以下です。

Hello A
Hello A
Hello B
Hello B
Bye A
Hello B

けれど、実際の出力は以下になります。

Hello A
Hello A
Hello A
Hello A
Bye A
Bye A

結論

明らかに期待と違う結果になる為、staticフィールドで値を保持するのは避けた方が良さそうです。

特にprotectedにして子クラスからアクセス可能にすると、バグの温床になりそうな予感がすごくあります。