読者です 読者をやめる 読者になる 読者になる

PHP5.3で導入された 名前空間

名前空間とは

2009年にPHP5.3.0のバージョンが出たことで、PHPに『名前空間』というものが導入されました。

名前空間』を使うと、クラスや関数に名前をつける際に、他の人が作ったライブラリで使われてるクラスや関数の名前と一緒になってしまう(業界用語で被る)のを避けることができるようです。

イメージ図

f:id:ts0818:20151030184903p:plain

 

⇩  PHPマニュアルの名前空間については下記へ

PHP: 名前空間 - Manual

 

名前空間の定義

PHP: 名前空間の定義 - Manual によると、

名前空間の定義

(PHP 5 >= 5.3.0)

PHP のコードならなんでも名前空間に含めることができますが、 実際に名前空間の影響を受けるのはクラス (抽象クラスやトレイトを含む) とインターフェイス、関数、そして定数だけです
変数やdefineによって定義される定数には名前空間は適用されず、名前空間がない場合と同様に参照されます

名前空間を宣言するには、キーワード namespace を使用します。
名前空間を含むファイルでは、他のコードより前にファイルの先頭で名前空間を宣言しなければなりません。 ただし declare キーワードは例外です。

例1 名前空間の宣言

<?php
namespace MyProject;

const 
CONNECT_OK 1;
class 
Connection /* ... */ }
function 
connect() { /* ... */ }

?>

名前空間の宣言より前に書くことが許されているコードは declare文のみです。
ソースファイルのエンコーディングを定義するために使用します。
さらに、PHP コード以外であっても名前空間の宣言の前に記述することはできません (スペースも同様です)

例2 名前空間の宣言

<html>
<?php
namespace MyProject// fatal error - namespace must be the first statement in the script
?>

さらに、他の PHP の制御構造とは異なり、同一の名前空間複数のファイルで定義することができます。
これにより、ひとつの名前空間の内容をファイルシステム上で分割することができます。

 

名前空間の階層構造

PHP: サブ名前空間の宣言 - Manual によると、

サブ名前空間の宣言

(PHP 5 >= 5.3.0)

ディレクトリやファイルと同様、PHP名前空間においても名前空間の階層構造を指定することができます。
このようにして名前空間を定義します。

例1 階層つきの名前空間の宣言

<?php
namespace MyProject\Sub\Level;

const 
CONNECT_OK 1;
class 
Connection /* ... */ }
function 
connect() { /* ... */  }

?>

上の例は、
定数   
MyProject\Sub\Level\CONNECT_OK  と
クラス  
MyProject\Sub\Level\Connection 
そして関数  
MyProject\Sub\Level\connect  を作成します。 

 

複数名前空間を同一ファイル内で使うとき

PHP: 同一ファイル内での複数の名前空間の定義 - Manual によると、

同一ファイル内での複数名前空間の定義

(PHP 5 >= 5.3.0)

複数名前空間を同一ファイル内で宣言することもあります。
この場合の構文は次の 2 通りです。

例1 シンプルな組み合わせ方式による複数名前空間の宣言

<?php
namespace MyProject;

const 
CONNECT_OK 1;
class 
Connection /* ... */ }
function 
connect() { /* ... */  }

namespace 
AnotherProject;

const 
CONNECT_OK 1;
class 
Connection /* ... */ }
function 
connect() { /* ... */  }
?>

この構文は、複数名前空間をひとつのファイルに含める場合の方法としてはお勧めしません。
かわりに、次の波括弧構文を使うことを推奨します。

例2 波括弧構文による複数名前空間の宣言

<?php
namespace MyProject {

const 
CONNECT_OK 1;
class 
Connection /* ... */ }
function 
connect() { /* ... */  }
}

namespace 
AnotherProject {

const 
CONNECT_OK 1;
class 
Connection /* ... */ }
function 
connect() { /* ... */  }
}
?>

ただ、複数名前空間をひとつのファイルに記述するようなコーディングはできるだけ避けるべきです。
主な使い道としては、複数PHP スクリプトをひとつのファイルにまとめるときくらいでしょう。

名前空間に属さないグローバルなコードを名前空間つきのコードと組み合わせるときには、 波括弧構文しか使用できません。
グローバルなコードは、名前空間の名前を指定しない namespace 文で囲みます。
たとえば次のようになります。

例3 複数名前空間および名前空間に属さないコードの宣言

<?php
namespace MyProject {

const 
CONNECT_OK 1;
class 
Connection /* ... */ }
function 
connect() { /* ... */  }
}

namespace { 
// グローバルコード
session_start();
$a MyProject\connect();
echo 
MyProject\Connection::start();
}
?>

namespace の波括弧の外側に書くことができる PHP コードは、最初の declare 文だけです。

例4 複数名前空間および名前空間に属さないコードの宣言

<?php
declare(encoding='UTF-8');
namespace 
MyProject {

const 
CONNECT_OK 1;
class 
Connection /* ... */ }
function 
connect() { /* ... */  }
}

namespace { 
// global code
session_start();
$a MyProject\connect();
echo 
MyProject\Connection::start();
}
?>

名前解決のルール

PHP: 名前解決のルール - Manual によると、

名前解決のルール

(PHP 5 >= 5.3.0)

名前解決のルールを説明するにあたって、いくつかの重要な定義を示しておきます。

名前空間名の定義

非修飾名

これは名前空間区切り文字を含まない識別子で、Foo のようなものです。

修飾名

これは名前空間区切り文字を含む識別子で、Foo\Bar のようなものです。

完全修飾名

これは名前空間区切り文字を含む識別子のうち先頭が名前空間区切り文字で始まるもので、 \Foo\Bar のようなものです。名前空間 \Foo も完全修飾名です。

名前解決は、これらの解決ルールによって行われます。

  1. 完全修飾された関数、クラス、定数へのコールはコンパイル時に解決されます。
    たとえば、new \A\BA\B クラスと解釈されます。
  2. 非修飾名および (完全修飾でない) 修飾名の変換は、現在のインポートルールに基づいてコンパイル時に行われます。
    たとえば、名前空間 A\B\CC という名前でインポートされている場合、 C\D\e( ) へのコールは A\B\C\D\e( ) と変換されます。
  3. 名前空間内で、インポートルールによる変換が行われなかった修飾名は 現在の名前空間が先頭に付加されます。
    たとえば、C\D\e( ) へのコールが名前空間 A\B 内で行われた場合、それはA\B\C\D\e( ) に変換されます。
  4. 非修飾クラス名の変換は、現在のインポートルールに基づいてコンパイル時に行われます (インポートされた短い名前がフルネームに置き換わります)。
    たとえば、 名前空間 A\B\C が C という名前でインポートされている場合、 new C( )new A\B\C( )と変換されます。
  5. 名前空間内 (ここでは A\B としましょう) で、非修飾な関数へのコールは実行時に解決されます。
    関数 foo( ) のコールは、次のように解決されます。
    1. まず現在の名前空間から関数 A\B\foo( ) を探します。
    2. 次に グローバル 関数 foo( ) を探します。
  6. 名前空間内 (ここでは A\B としましょう) で、 非修飾あるいは (完全修飾でない) 修飾なクラスへのコールは実行時に解決されます。
    new C( )new D\E( ) がどのように解決されるかを示します。
    new C( ) の場合は、
    1. まず現在の名前空間からクラス A\B\C を探します。
    2. A\B\C を autoload します。
    new D\E( ) の場合は、
    1. 現在の名前空間を先頭につけた A\B\D\E を探します。
    2. A\B\D\E を autoload します。
    グローバル名前空間内のグローバルクラスを参照するには、完全修飾形式の new \C( ) を使わなければなりません。

例1 名前解決の例

<?php
namespace A;
use 
B\DC\as F;

// 関数のコール

foo();      // まず名前空間 "A" で定義されている "foo" のコールを試み、
            // 次にグローバル関数 "foo" をコールします

\foo();     // グローバルスコープで定義されている関数 "foo" をコールします

my\foo();   // 名前空間 "A\my" で定義されている関数 "foo" をコールします

F();        // まず名前空間 "A" で定義されている "F" のコールを試み、
            // 次にグローバル関数 "F" をコールします

// クラスの参照

new B();    // 名前空間 "A" で定義されているクラス "B" のオブジェクトを作成します
            // 見つからない場合は、クラス "A\B" の autoload を試みます

new D();    // インポートルールを使用し、名前空間 "B" で定義されているクラス "D" のオブジェクトを作成します
            // 見つからない場合は、クラス "B\D" の autoload を試みます

new F();    // インポートルールを使用し、名前空間 "C" で定義されているクラス "E" のオブジェクトを作成します
            // 見つからない場合は、クラス "C\E" の autoload を試みます

new \B();   // グローバルスコープで定義されているクラス "B" のオブジェクトを作成します
            // 見つからない場合は、クラス "B" の autoload を試みます

new \D();   // グローバルスコープで定義されているクラス "D" のオブジェクトを作成します
            // 見つからない場合は、クラス "D" の autoload を試みます

new \F();   // グローバルスコープで定義されているクラス "F" のオブジェクトを作成します
            // 見つからない場合は、クラス "F" の autoload を試みます

// 別の名前空間から使用する静的メソッド/関数

B\foo();    // 名前空間 "A\B" の関数 "foo" をコールします

B::foo();   // 名前空間 "A" で定義されているクラス "B" のメソッド "foo" をコールします
            // クラス "A\B" が見つからない場合はクラス "A\B" の autoload を試みます

D::foo();   // インポートルールを使用し、名前空間 "B" で定義されているクラス "D" のメソッド "foo" をコールします
            // クラス "B\D" が見つからない場合はクラス "B\D" の autoload を試みます

\B\foo();   // 名前空間 "B" の関数 "foo" をコールします

\B::foo();  // グローバルスコープのクラス "B" のメソッド "foo" をコールします
            // クラス "B" が見つからない場合はクラス "B" の autoload を試みます

// 現在の名前空間から使用する静的メソッド/関数

A\B::foo();   // 名前空間 "A\A" のクラス "B" のメソッド "foo" をコールします
              // クラス "A\A\B" が見つからない場合はクラス "A\A\B" の autoload を試みます

\A\B::foo();  // 名前空間 "A" のクラス "B" のメソッド "foo" をコールします
              // クラス "A\B" が見つからない場合はクラス "A\B" の autoload を試みます
?>

  

名前空間の使用法

PHP: 名前空間の使用法: 基本編 - Manual によると、

名前空間の使用法: 基本編

(PHP 5 >= 5.3.0)

名前空間の使い方についてあれこれ言う前に、まずは PHP がどのようにしてコード中の要素の名前空間を知るのかを理解しておくことが重要です。
PHP名前空間は、ファイルシステムにたとえて考えることができます。
たとえば、ファイルシステム内のファイルにアクセスするには次の 3 つの方法があります。

  1. foo.txt のような相対ファイル名を使う。
    これは  currentdirectory/foo.txt  と解釈されます。
    ここで、 currentdirectory は現在いるディレクトリを表します。
    したがって、カレントディレクトリが /home/foo であった場合はこれは /home/foo/foo.txt となります。
  2. subdirectory/foo.txt のような相対パス名を使う。
    これは  currentdirectory/subdirectory/foo.txt  と解釈されます。
  3. /main/foo.txt のような絶対パス名を使う。
    これは /main/foo.txt と解釈されます。

PHP名前空間内の要素についても同じ理屈があてはまります。
たとえば、クラス名を参照するには次の 3 つの方法があります。

  1. $a = new foo( ); あるいは foo::staticmethod( ); のような非修飾名 あるいはプレフィックスなしのクラス名。
    現在の名前空間が  currentnamespace  である場合、これは  currentnamespace\foo  と解釈されます。
    名前空間に属さないグローバルなコードにおいては、これは foo と解釈されます。

    注意: 修飾されていない関数や定数は、名前空間内にその関数や定数がなければ グローバルな関数あるいは変数とみなされます。
    詳細は 名前空間の使用法: グローバルな関数/定数への移行 を参照ください。
  2. $a = new subnamespace\foo( ); あるいはsubnamespace\foo::staticmethod( ); のような修飾名 あるいはプレフィックスつきクラス名。
    現在の名前空間が  currentnamespace  である場合、これは  currentnamespace\subnamespace\foo と解釈されます。
    名前空間に属さないグローバルなコードにおいては、これはsubnamespace\foo と解釈されます。
  3. $a = new \currentnamespace\foo( ); あるいは \currentnamespace\foo::staticmethod( ); のような完全修飾名 あるいはグローバルプレフィックス演算子つきのクラス名。
    これは、常にコードで記述されたとおりの名前であるcurrentnamespace\foo と解釈されます。

これら 3 つの構文を実際のコードで使う例を次に示します。

file1.php

<?php
namespace Foo\Bar\subnamespace;

const 
FOO 1;
function 
foo() {}
class 
foo
{
    static function 
staticmethod() {}
}
?>

file2.php

<?php
namespace Foo\Bar;
include 
'file1.php';

const 
FOO 2;
function 
foo() {}
class 
foo
{
    static function 
staticmethod() {}
}

/* 非修飾名 */
foo(); // Foo\Bar\foo 関数と解釈されます
foo::staticmethod(); // Foo\Bar\foo クラスの staticmethod メソッドと解釈されます
echo FOO// 定数 Foo\Bar\FOO と解釈されます

/* 修飾名 */
subnamespace\foo(); // Foo\Bar\subnamespace\foo 関数と解釈されます
subnamespace\foo::staticmethod(); // Foo\Bar\subnamespace\foo クラスの
                                  // staticmethod メソッドと解釈されます
echo subnamespace\FOO// 定数 Foo\Bar\subnamespace\FOO と解釈されます
                                  
/* 完全修飾名 */
\Foo\Bar\foo(); // Foo\Bar\foo 関数と解釈されます
\Foo\Bar\foo::staticmethod(); // Foo\Bar\foo クラスの staticmethod メソッドと解釈されます
echo \Foo\Bar\FOO// 定数 Foo\Bar\FOO と解釈されます
?>

グローバルなクラス、関数あるいは定数にアクセスするには、完全修飾名を使用して \strlen( )\Exception あるいは \INI_ALL などとすることができます。

例1 グローバルなクラス、関数および定数への名前空間内からのアクセス

<?php
namespace Foo;

function 
strlen() {}
const 
INI_ALL 3;
class 
Exception {}

$a = \strlen('hi'); // グローバル関数 strlen をコールします
$b = \INI_ALL// グローバル定数 INI_ALL にアクセスします
$c = new \Exception('error'); // グローバルクラス Exception のインスタンスを作成します
?>

名前空間動的言語機能

PHP: 名前空間と動的言語機能 - Manual によると、

名前空間動的言語機能

(PHP 5 >= 5.3.0)

PHP における名前空間の実装は、PHP 自身が動的プログラミング言語であるという性質に影響を受けています。
したがって、次の例のようなコードを名前空間を使って書き直すには

例1 要素への動的なアクセス

example1.php:

<?php
class classname
{
    function 
__construct()
    {
        echo 
__METHOD__,"\n";
    }
}
function 
funcname()
{
    echo 
__FUNCTION__,"\n";
}
const 
constname "global";

$a 'classname';
$obj = new $a// classname::__construct と表示します
$b 'funcname';
$b(); // funcname と表示します
echo constant('constname'), "\n"// global と表示します
?>

完全修飾名 (クラス名に名前空間プレフィックスをつけたもの) を使う必要があります。
動的なクラス名、関数名あるいは定数名においては修飾名と完全修飾名に差はないので、 先頭のバックスラッシュはなくてもかまいません。

例2 名前空間つき要素への動的なアクセス

<?php
namespace namespacename;
class 
classname
{
    function 
__construct()
    {
        echo 
__METHOD__,"\n";
    }
}
function 
funcname()
{
    echo 
__FUNCTION__,"\n";
}
const 
constname "namespaced";

include 
'example1.php';

$a 'classname';
$obj = new $a// classname::__construct と表示します
$b 'funcname';
$b(); // funcname と表示します
echo constant('constname'), "\n"// global と表示します

/* ダブルクォートを使う場合は "\\namespacename\\classname" としなければなりません */
$a '\namespacename\classname';
$obj = new $a// namespacename\classname::__construct と表示します
$a 'namespacename\classname';
$obj = new $a// これも namespacename\classname::__construct と表示します
$b 'namespacename\funcname';
$b(); // namespacename\funcname と表示します
$b '\namespacename\funcname';
$b(); // これも namespacename\funcname と表示します
echo constant('\namespacename\constname'), "\n"// namespaced と表示します
echo constant('namespacename\constname'), "\n"// これも namespaced と表示します
?>

文字列中の名前空間名のエスケープに関する注意 を読んでおくことを忘れないようにしましょう。 

 

namespaceキーワードと__NAMESPACE__定数

PHP: namespace キーワードおよび __NAMESPACE__ 定数 - Manual によると、

namespace キーワードおよび __NAMESPACE__ 定数

(PHP 5 >= 5.3.0)

PHP には、現在の名前空間内の要素へのアクセスを抽象化するための方法が 2 通りあります。
マジック定数 __NAMESPACE__ およびnamespace キーワードがそれです。

__NAMESPACE__ の値は文字列で、現在の名前空間の名前が格納されます。
名前空間に属さないグローバルなコードでは、この中身は空文字列となります。

例1 名前空間内のコードでの __NAMESPACE__ の例

<?php
namespace MyProject;

echo 
'"'__NAMESPACE__'"'// "MyProject" と出力します
?>

例2 グローバルなコードでの __NAMESPACE__ の例

<?php

echo '"'__NAMESPACE__'"'// "" と出力します
?>

__NAMESPACE__ 定数は、動的に名前を作成する場合に便利です。
たとえば次のようになります。
 

例3 __NAMESPACE__ による動的な名前の作成

<?php
namespace MyProject;

function 
get($classname)
{
    
$a __NAMESPACE__ '\\' $classname;
    return new 
$a;
}
?>

namespace キーワードを使用すると、 現在の名前空間あるいはサブ名前空間内の要素を明示的に指定することができます。
これは、クラスにおける self 演算子と同じ意味合いのものです。

例4 名前空間内での namespace 演算子

<?php
namespace MyProject;

use 
blah\blah as mine// "名前空間の使用法: エイリアス/インポート" を参照ください

blah\mine(); // MyProject\blah\mine() 関数をコールします
namespace\blah\mine(); // MyProject\blah\mine() 関数をコールします

namespace\func(); // MyProject\func() 関数をコールします
namespace\sub\func(); // MyProject\sub\func() 関数をコールします
namespace\cname::method(); // MyProject\cname クラスの静的メソッド "method" をコールします
$a = new namespace\sub\cname(); // MyProject\sub\cname クラスのオブジェクトのインスタンスを作成します
$b = namespace\CONSTANT// 定数 MyProject\CONSTANT の値を $b に代入します
?>

例5 グローバルコードでの namespace 演算子

<?php

namespace\func(); // func() 関数をコールします
namespace\sub\func(); // sub\func() 関数をコールします
namespace\cname::method(); // cname クラスの静的メソッド "method" をコールします
$a = new namespace\sub\cname(); // sub\cname クラスのオブジェクトのインスタンスを作成します
$b = namespace\CONSTANT// 定数 CONSTANT の値を $b に代入します
?>

インポートのルール

PHP: 名前空間の使用法: エイリアス/インポート - Manualによると、

名前空間の使用法: エイリアス/インポート

(PHP 5 >= 5.3.0)

外部の完全修飾名をエイリアスで参照したりインポートしたりする機能は、 名前空間において非常に重要なものです。
これは、Unix 系のファイルシステムでファイルやディレクトリへのシンボリックリンクを作成することに似ています。

PHP名前空間では、3 通りの方法でエイリアスやインポートをサポートしています。


PHP 5.6 以降では、さらに関数や定数のエイリアスやインポートもサポートします。

PHP でのエイリアス作成には use 演算子を使用します。
ここに、5 種類すべてのインポート方法の例を示します。

例1 use 演算子によるインポート/エイリアス

<?php
namespace foo;
use 
My\Full\Classname as Another;

// これは use My\Full\NSname as NSname と同じです
use My\Full\NSname;

// グローバルクラスをインポートします
use ArrayObject;

// 関数をインポートします (PHP 5.6+)
use function My\Full\functionName;

// 関数のエイリアスを定義します (PHP 5.6+)
use function My\Full\functionName as func;

// 定数をインポートします (PHP 5.6+)
use const My\Full\CONSTANT;

$obj = new namespace\Another// foo\Another クラスのオブジェクトのインスタンスを作成します
$obj = new Another// My\Full\Classname クラスのオブジェクトのインスタンスを作成します
NSname\subns\func(); // My\Full\NSname\subns\func 関数をコールします
$a = new ArrayObject(array(1)); // ArrayObject クラスのオブジェクトのインスタンスを作成します
// "use ArrayObject" がなければ、foo\ArrayObject クラスのオブジェクトのインスタンスを作成することになります
func(); // 関数 My\Full\functionName を呼びます
echo CONSTANT// 定数 My\Full\CONSTANT の値を表示します
?>

名前空間つきの名前 (完全修飾形式の名前空間は区切り文字を含んだ Foo\Bar のようなもので、グローバルな場合は区切り文字を含まない FooBar のようになります) では先頭のバックスラッシュは不要で、推奨されないことに注意しましょう。
インポートする名前は完全修飾形式でなければならず、 現在の名前空間からの相対指定で処理されることはないからです。

PHP では、複数の use 文を同一行に置くための便利なショートカットもサポートしています。

例2 use 演算子によるインポート/エイリアスで、複数の use 文を組み合わせる例

<?php
use My\Full\Classname as AnotherMy\Full\NSname;

$obj = new Another// My\Full\Classname クラスのオブジェクトのインスタンスを作成します
NSname\subns\func(); // My\Full\NSname\subns\func 関数をコールします
?>

インポートはコンパイル時に行われるので、動的なクラス名、関数名や定数名には影響を及ぼしません。

例3 インポートと動的名

<?php
use My\Full\Classname as AnotherMy\Full\NSname;

$obj = new Another// My\Full\Classname クラスのオブジェクトのインスタンスを作成します
$a 'Another';
$obj = new $a;      // Another クラスのオブジェクトのインスタンスを作成します
?>

さらにインポートの影響が及ぶのは非修飾名および修飾名のみです。
完全修飾名は絶対的なものであり、インポートの影響を受けることはありません。

例4 インポートと完全修飾名

<?php
use My\Full\Classname as AnotherMy\Full\NSname;

$obj = new Another// My\Full\Classname クラスのオブジェクトのインスタンスを作成します
$obj = new \Another// Another クラスのオブジェクトのインスタンスを作成します
$obj = new Another\thing// My\Full\Classname\thing クラスのオブジェクトのインスタンスを作成します
$obj = new \Another\thing// Another\thing クラスのオブジェクトのインスタンスを作成します
?>

インポート時のスコープ規則

use キーワードの宣言は、ファイル内の一番外側のスコープ (グローバルスコープ) あるいは名前空間宣言の中で行わなければなりません。
これは、インポートが実行時ではなくコンパイル時に行われるためです。
ブロック内のスコープではインポートできません。

次の例は、use キーワードの間違った使い方を示すものです。

例5 間違ったインポートの例

<?php
namespace Languages;

class 
Greenlandic
{
    use 
Languages\Danish;

    ...
}
?>

注意:

インポート規則はファイル単位のものです。
つまり、インクルードされたファイルは インクロード元の親ファイルのインポート規則を 引き継ぎません

use 宣言のグループ化

PHP 7.0 以降では、同じ namespace から複数のクラスや関数そして定数をインポートする際に、 それらをひとつの use にまとめられるようになりました。

<?php

// 以前のバージョンのコード
use some\namespace\ClassA;
use 
some\namespace\ClassB;
use 
some\namespace\ClassC as C;

use function 
some\namespace\fn_a;
use function 
some\namespace\fn_b;
use function 
some\namespace\fn_c;

use const 
some\namespace\ConstA;
use const 
some\namespace\ConstB;
use const 
some\namespace\ConstC;

// PHP 7 以降のコード
use some\namespace\{ClassAClassBClassC as C};
use function 
some\namespace\{fn_afn_bfn_c};
use const 
some\namespace\{ConstAConstBConstC};

グローバル

PHP: グローバル空間 - Manual によると、

グローバル空間

(PHP 5 >= 5.3.0)

名前空間の定義がない場合、すべてのクラスや関数の定義はグローバル空間に配置されます。
これは、名前空間に対応する前の PHP がサポートしていた空間です。
名前の先頭に \ をつけると、 名前空間の内部からであってもグローバル空間の名前を指定することができます。

例1 グローバル空間を指定する方法

<?php
namespace A\B\C;

/* この関数は A\B\C\fopen です */
function fopen() { 
     
/* ... */
     
$f = \fopen(...); // グローバルな fopen をコールします
     
return $f;

?>

名前空間の解決の優先順位

PHP: 名前空間の使用法: グローバル関数/定数への移行 - Manualによると、

名前空間の使用法: グローバル関数/定数への移行

(PHP 5 >= 5.3.0)

名前空間内で、PHP が未定義のクラス名や関数、定数に出会った場合、 それぞれに応じて異なる優先順位で解決を行います。
クラス名は、常に現在の名前空間での名前として解釈されます。
したがって、内部クラスあるいは名前空間に属さないクラスにアクセスするには 次のように完全修飾名で指定しなければなりません。

例1 名前空間内からのグローバルクラスへのアクセス

<?php
namespace A\B\C;
class 
Exception extends \Exception {}

$a = new Exception('hi'); // $a は A\B\C\Exception クラスのオブジェクトです
$b = new \Exception('hi'); // $b は Exception クラスのオブジェクトです

$c = new ArrayObject// fatal error, class A\B\C\ArrayObject not found
?>

関数や定数の場合、名前空間内にその関数や定数が見つからなければ PHP はグローバル関数/定数を探します。

例2 名前空間内からのグローバル関数/定数への移行

<?php
namespace A\B\C;

const 
E_ERROR 45;
function 
strlen($str)
{
    return \
strlen($str) - 1;
}

echo 
E_ERROR"\n"// "45" と表示します
echo INI_ALL"\n"// "7" と表示します - グローバルの INI_ALL に移行しました

echo strlen('hi'), "\n"// "1" と表示します
if (is_array('hi')) { // "is not array" と表示します
    
echo "is array\n";
} else {
    echo 
"is not array\n";
}
?>

名前空間について

PHP: FAQ: 名前空間について知っておくべきこと - Manualによると、

FAQ: 名前空間について知っておくべきこと

(PHP 5 >= 5.3.0)

この FAQ は 2 つに別れています。一般的な質問と、 深く理解するために有用な実装に関する質問です。

まずは一般的な質問。

  1. 名前空間を使わない場合、 何か注意すべきことはありますか?
  2. 名前空間内での内部クラスあるいはグローバルクラスの使用法は?
  3. 同じ名前空間にあるクラス、関数あるいは定数を使用する方法は?
  4. \my\name\name のような名前はどのように解決される?
  5. my\name のような名前はどのように解決される?
  6. 修飾されていない name のようなクラス名はどのように解決される?
  7. 修飾されていない name のような関数名/定数名はどのように解決される?

また、名前空間の実装を理解するために有用な実装の詳細は次のとおりです。

  1. インポートした名前が同一ファイルで定義されているクラスと衝突しない
  2. 名前空間のネストはできない
  3. 関数や定数は use 文でインポートできない
  4. 動的な名前空間名 (クォートした名前) ではバックスラッシュのエスケープが必要
  5. バックスラッシュを含む未定義な定数を参照すると、致命的なエラーが発生する
  6. 特別な定数 NULL, TRUE, FALSE, ZEND_THREAD_SAFE そして ZEND_DEBUG_BUILD は上書きできない

 

名前空間については下記サイトへ

PHP V5.3 の名前空間を利用して、理解しやすく保守の容易なコードを作成する

PHPのnamespace(名前空間)について - 麹町で働くWebエンジニアのメモ帳

第1回 PHP 5.3の概要と名前空間,レイトスタティックバインディング:PHP 5.3の新機能と変更点|gihyo.jp … 技術評論社

既存のPHPを5.3の名前空間仕様に置き換えてみたときのメモ ::ハブろぐ

 

広告を非表示にする