(PHP 5 >= 5.3.0, PHP 7, PHP 8)
この FAQ は 2 つに別れています。一般的な質問と、 深く理解するために有用な実装に関する質問です。
まずは一般的な質問。
\my\name
や \name
のような名前はどのように解決される?
my\name
のような名前はどのように解決される?
name
のようなクラス名はどのように解決される?
name
のような関数名/定数名はどのように解決される?
また、名前空間の実装を理解するために有用な実装の詳細は次のとおりです。
いいえ。これまで書いてきたコード、今後書く名前空間を含まないコードのいずれについても、 名前空間が何らかの影響を及ぼすことはありません。 お望みなら名前空間を使わないコードを書くこともできます。
例1 名前空間の外部にあるグローバルクラスへのアクセス
<?php
$a = new \stdClass;
?>
これは、機能的に次と同等です。
例2 名前空間の外部にあるグローバルクラスへのアクセス
<?php
$a = new stdClass;
?>
例3 名前空間内からの内部クラスへのアクセス
<?php
namespace foo;
$a = new \stdClass;
function test(\ArrayObject $parameter_type_example = null) {}
$a = \DirectoryIterator::CURRENT_AS_FILEINFO;
// 内部クラス/グローバルクラスの継承
class MyException extends \Exception {}
?>
例4 名前空間内のクラス、関数あるいは定数へのアクセス
<?php
namespace foo;
class MyClass {}
// 現在の名前空間のクラスを引数の型として使う
function test(MyClass $parameter_type_example = null) {}
// 現在の名前空間のクラスを引数の型として使うもうひとつの方法
function test(\foo\MyClass $parameter_type_example = null) {}
// 現在の名前空間のクラスの継承
class Extended extends MyClass {}
// グローバル関数へのアクセス
$a = \globalfunc();
// グローバル定数へのアクセス
$b = \INI_ALL;
?>
\my\name
や \name
のような名前はどのように解決される?
\
から始まる名前は常に見た目のままに解釈されます。
つまり \my\name
は my\name
であり、
\Exception
は Exception
となります。
例5 完全修飾名
<?php
namespace foo;
$a = new \my\name(); // "my\name" クラスのインスタンスを作成します
echo \strlen('hi'); // "strlen" 関数をコールします
$a = \INI_ALL; // $a に定数 "INI_ALL" の値を設定します
?>
my\name
のような名前はどのように解決される?
名前にバックスラッシュを含むが先頭はバックスラッシュでない名前、たとえば
my\name
のような名前は 2 通りの方法で解釈されます。
別の名前に my
というエイリアスを指定する import
文がある場合は、そのエイリアスが my\name
の my
部分に適用されます。
それ以外の場合は、現在の名前空間が my\name
の先頭に付け加えられます。
例6 修飾名
<?php
namespace foo;
use blah\blah as foo;
$a = new my\name(); // "foo\my\name" クラスのインスタンスを作成します
foo\bar::name(); // "blah\blah\bar" のstaticメソッド "name" をコールします
my\bar(); // "foo\my\bar" 関数をコールします
$a = my\BAR; // $a に定数 "foo\my\BAR" の値を設定します
?>
name
のようなクラス名はどのように解決される?
バックスラッシュを含まない name
のようなクラス名は
2 通りの方法で解釈されます。
別の名前に name
というエイリアスを指定する import
文がある場合は、そのエイリアスが適用されます。
それ以外の場合は、現在の名前空間が name
の先頭に付け加えられます。
例7 非修飾クラス名
<?php
namespace foo;
use blah\blah as foo;
$a = new name(); // "foo\name" クラスのインスタンスを作成します
foo::name(); // "blah\blah" クラスのstaticメソッド "name" をコールします
?>
name
のような関数名/定数名はどのように解決される?
バックスラッシュを含まない name
のような関数名/定数名は
2 通りの方法で解釈されます。
まず、現在の名前空間が name
の先頭に付け加えられます。
現在の名前空間に name
という関数あるいは定数がない場合は、
グローバル関数あるいは定数に name
があればそれを使用します。
例8 非修飾関数/定数名
<?php
namespace foo;
use blah\blah as foo;
const FOO = 1;
function my() {}
function foo() {}
function sort(&$a)
{
\sort($a); // グローバル関数 "sort" をコールします
$a = array_flip($a);
return $a;
}
my(); // "foo\my" をコールします
$a = strlen('hi'); // "foo\strlen" が存在しないので、グローバル関数 "strlen" をコールします
$arr = array(1,3,2);
$b = sort($arr); // "foo\sort" 関数をコールします
$c = foo(); // calls function "foo\foo" - import is not applied
$a = FOO; // sets $a to value of constant "foo\FOO" - import is not applied
$b = INI_ALL; // sets $b to value of global constant "INI_ALL"
?>
次のようなスクリプトの組み合わせは、正当なものです。
file1.php
<?php
namespace my\stuff;
class MyClass {}
?>
another.php
<?php
namespace another;
class thing {}
?>
file2.php
<?php
namespace my\stuff;
include 'file1.php';
include 'another.php';
use another\thing as MyClass;
$a = new MyClass; // 名前空間 another のクラス "thing" のインスタンスを作成します。
?>
MyClass
クラスが名前空間
my\stuff
にあるとはいえ、名前の衝突はありません。
MyClass の定義は別のファイルにあるからです。
しかし、次の例は名前の衝突による致命的なエラーとなります。
MyClass の定義が同じファイル上の use 文で行われているからです。
<?php
namespace my\stuff;
use another\thing as MyClass;
class MyClass {} // fatal error: MyClass conflicts with import statement
$a = new MyClass;
?>
PHP では名前空間のネストはできません。
<?php
namespace my\stuff {
namespace nested {
class foo {}
}
}
?>
<?php
namespace my\stuff\nested {
class foo {}
}
?>
バックスラッシュは文字列のエスケープ文字として使われることに注意しましょう。 文字列の中で使う際にはバックスラッシュを二重に書く必要があります。 そうしないと、予期せぬ結果を引き起こしてしまいます。
例9 ダブルクォートで囲んだ文字列内で名前空間名を扱う際の危険
<?php
$a = "dangerous\name"; // ダブルクォートの中では \n が改行文字になってしまいます!
$obj = new $a;
$a = 'not\at\all\dangerous'; // これなら大丈夫です
$obj = new $a;
?>
未定義の定数のうち FOO
のような修飾されていないものは、
PHP が FOO
を定数の値と解釈したという notice が発生します。
修飾あるいは完全修飾形式の定数、つまりバックスラッシュを含む定数の場合、
それが未定義なら致命的なエラーが発生します。
例10 未定義の定数
<?php
namespace bar;
$a = FOO; // notice - undefined constants "FOO" assumed "FOO";
$a = \FOO; // fatal error, undefined namespace constant FOO
$a = Bar\FOO; // fatal error, undefined namespace constant bar\Bar\FOO
$a = \Bar\FOO; // fatal error, undefined namespace constant Bar\FOO
?>
名前空間内で特別な組み込み定数を定義しようとすると、致命的なエラーが発生します。
例11 未定義の定数
<?php
namespace bar;
const NULL = 0; // 致命的なエラー
const true = 'stupid'; // これも、致命的なエラー
// etc.
?>