PHPでの名前空間の定義と、その参照方法

  • PHP
  • 現在地

名前空間 (namespace)

名前空間 (namespace) は、名前の衝突を防ぐために細分化された、名前を定義するための空間のことです。

名前空間を定義していない場合グローバル空間 (grobalspace) に定義されるのですが、1つの空間で同名の名前を定義することができないため、外部から読み込んだファイルに同名の項目があれば、名前の衝突が起き二重の定義が原因となりエラーが引き起こされてしまいます。

クラスと関数なら 「Fatal error: Cannot redeclare」定数なら「Notice: Constant ~ already defined 」といったエラーが出ます。

名前空間を定義することで、こういった名前の衝突による問題を防ぎつつ、空間を介して同名の項目を別々に参照することが可能になります。

名前空間の使い方

  • 名前空間の定義

    名前空間を定義するには、下記のように空間名を namespace で宣言します。

    namespace e;

    名前空間の宣言をする場合、空間の外となる宣言前の部分は、decrale 文以外のコードは利用できず、宣言後の記述は、新たな名前空間の宣言が無い限り、すべてその空間に含まれることとなります。

    ただし影響を受けるのは、定義を必要とするクラス・インターフェース・関数・定数の名前のみです。

    階層を踏まえた空間を作成する場合は、バックスラッシュ (\) で区切ります。(日本語環境では半角¥記号)

    また、(推奨されていませんが)1つのファイル内に複数の名前空間を宣言する場合は、空間名の後にセミコロン (;) を置かず、波括弧 {} の中でコードを記述することで可能です。

    以下はサンプルです。

    • <?php
    • namespace e\a\t{
      • define('VERB','食べる');
      • class MeanDate{
        • function write(){
          • $name = new \ReflectionClass($this);
          • echo preg_replace('/\\\/','',$name->getNamespaceName()).'='.VERB;
        • }
      • }
    • }
    • namespace{
      • $e = new \e\a\t\MeanDate;
      • $e->write();
    • }
    • ?>

    空間名なしの namespace{} は、名前空間を定義していない場合と同様で、グローバル空間に記述するものと同様となります。

  • 名前空間を介した参照

    名前空間内の項目や階層を踏まえた空間は、'\' でつないで参照することができます。

    参照する際の名前は、下記の3種類の記述方法があります。

    非修飾名(名前のみ)による参照
    その名前空間内で定義されている名前の参照を行い、無ければグローバル空間から参照を行います。

    ただし、クラスのみグローバルからの参照を行いません。
    上記のサンプルで ReflectionClass を完全修飾名で参照しているのはそのためです。

    修飾名(空間名 \ 名前)による参照
    修飾名による参照は、参照元の空間より下位の階層の空間を対象として相対的な記述を行う必要があります。
    a\t\MeanDate
    上記のサンプルで、名前空間 e の位置から t にある、クラス MeanDate を参照する場合。
    完全修飾名(\ 空間名 \ 名前)による参照
    先頭に '\' を記述したうえで、空間名と名前をすべて記述し参照。どこからでも参照できます。
    なお、モジュールで用意されている関数やクラスが、'\' を先頭に置いても変わらず動作するのは、グローバル空間に定義されているためです。

    名前空間を介した参照がいまいちピンとこない場合は、マニュアルでもファイルシステムに例えられているので、「名前」はファイル、「名前空間」はディレクトリ、「グローバル空間」はルートディレクトリとして置き換えて考えてみるといいかもしれません。

  • 空間名のインポートとエイリアス(別名)の作成

    完全修飾名を利用すると確実に参照できるのですが、深い階層がある場合はやたらと参照名が長くなってしまいます。

    そこで、use 演算子で宣言することで、その参照名の部分をインポートしたり、別名を作成することができます。

    対象となる名前空間は完全修飾名とみなされるので、先頭に '\' を付ける必要はありません。

    この例ではインポートを行い、名前空間名は 't' だけで参照することができるようになります。

    use e\a\t;

    この場合、'eat' が名前空間 'e\a\t' の別名となります。

    use e\a\t as eat;

    ただし、use 演算子による宣言はグローバルスコープにて行わなければならないため、上のサンプルでの \ReflectionClass を '\' 無しで書き直す場合は、MeanDate クラスを定義する前に use ReflectionClass; と宣言しておく必要があります。

  • 現在の名前空間名の取得

    上記のサンプルでは、名前空間名を取得するために ReflectionClass を実体化し getNamespaceName() で空間名を取得していますが、呼び出し元の空間名を利用したいだけなら以下のように書き直すことができます。

    echo preg_replace('/\\\/','',__NAMESPACE__).'='.VERB;

    これは定数 __NAMESPACE__ に、現在の名前空間名が格納されているため可能となります。

スポンサードリンク

inserted by FC2 system