PHP の static と self の違い
PHP の static
と self
の違いについてです。
基本中の基本なのですが、 PHP を書かない日が続くとどちらがどちらなのか忘れてしまい調べ直すことしきりなので、メモとして残しておきます。
まとめ
static
は 実行時 のクラスを指すself
は 定義時 のクラスを指す
詳細説明
static
は実行時の文脈でのクラスを指します。
つまり、 static
の利用場所が static メソッドの場合はレシーバのクラスを、通常のインスタンスメソッドの場合はレシーバはオブジェクトなのでそのクラスを指します。
他方の self
は定義時の文脈でのクラスを指します。
コードで確認してみましょう。
次のコードでは static
と self
の両方を使用しておりその違いを確認することができます。
class User
{
public static function loadByName($name)
{
$id = self::getIdForName($name);
return new static($id);
}
public static function getIdForName()
{
print __METHOD__ . PHP_EOL;
}
public function __construct($id)
{
print __METHOD__ . PHP_EOL;
}
}
class AdminUser extends User
{
public static function getIdForName()
{
print __METHOD__ . PHP_EOL;
}
public function __construct($id)
{
print __METHOD__ . PHP_EOL;
}
}
$admin1 = AdminUser::loadByName('ラファエロ');
// =>
// User::getIdForName
// AdminUser::__construct
getIdForName()
の呼び出しには self
が使われているため、 AdminUser
から loadByName()
が呼ばれたと場合でも呼び出されるメソッドは User
の getIdForName()
です( AdminUser
の getIdForName()
ではありません)。
一方、 __construct()
の呼び出しには( new static()
の形で) static
が使われているため、 AdminUser
から loadByName
が呼ばれたときには AdminUser
の __construct()
が使われます。
ちなみに、 static
のこの挙動は late static binding と呼ばれたりするようです(漢字にするとかえって意味がわかりづらいので英語のままで……)。
個人的に、 self
の方は直感的ですんなり頭に入ってきますが、 static
は「それは言葉の意味として違うんじゃないか」という気がして仕方ありません。
PHP はこういうところが多いのが使っていて辛いところです :(