綺麗に死ぬITエンジニア

PHPのclassキーワードによるクラス名の解決は、実際のクラスを参照していない

2017-02-14

PHPの落とし穴の一つ。

もしかしたら勘違いしている方がいるかもしれないので、マニアックな内容ですが紹介しておきます。

PHPのclassキーワード

PHPでは、特定のクラスのクラス名(名前空間を含む完全修飾名)を取得するとき、classキーワードを参照することで取得できます。

<?php
namespace NS {
    class ClassName {
    }

    echo ClassName::class;  // NS\ClassName
}

ひと昔前のPHPでは、クラス名を直接文字列で指定して、class_exists()class_parents()などのクラス名の文字列を利用する関数を使っていました。

しかし、PHP 5.5以降から、このclassキーワードが実装され、クラス名を指定する際にはこのclassキーワードを使うのが普通になりました。

classキーワードは定数ではない

この、classキーワード、まるでオブジェクト定数のように参照していますが、オブジェクト定数とは異なり、実際のクラスは参照していません

オブジェクト定数は、以下のようなクラス内で定義される定数です。

<?php
class ClassName
{
    const CONSTANT = 'constant value';
}

echo ClassName::CONSTANT;  // constant value

慣習的に、定数は普通、全て大文字のスネークケースとして定義しますが、実際には小文字も利用できます。なので、classはクラス内で予約された定数だと考えがちですが、実際には定数ではないのです。

その根拠として、存在しないクラスでclassキーワードを呼び出した場合、エラーにはならずそのまま処理されます。

// Klass は定義していない

echo Klass::class;  // Klass

echo Klass::CONSTANT;  // Warning: Uncaught Error: Class 'Klass' not found in php shell code:1

まとめ

PHPのclassキーワードはあくまでキーワードであり、クラスで予約された定数ではありません。

あまり問題になることはないとは思いますが、勘違いしやすい部分だと思うので、注意しましょう。

筆者について

フリーランスエンジニアとして活動している、「もりやませーた」です。

筆者のTwitterはこちら。記事に関するご意見等はTwitterの方へお寄せください。

その他業務に関するお問い合わせは、こちらのページをご覧ください。

PHP