この FAQ は 2 つに別れています。一般的な質問と、 深く理解するために有用な実装に関する質問です。
まずは一般的な質問。
また、名前空間の実装を理解するために有用な実装の詳細は次のとおりです。
いいえ。これまで書いてきたコード、今後書く名前空間を含まないコードのいずれについても、 名前空間が何らかの影響を及ぼすことはありません。 お望みなら名前空間を使わないコードを書くこともできます。
例1 名前空間の外部にあるグローバルクラスへのアクセス
<?php
$a = new \stdClass;
これは、機能的に次と同等です。
例2 名前空間の外部にあるグローバルクラスへのアクセス
<?php
$a = new stdClass;
例3 名前空間内からの内部クラスへのアクセス
<?php
namespace foo;
$a = new \stdClass;
function test(\ArrayObject $typehintexample = null) {}
$a = \DirectoryIterator::CURRENT_AS_FILEINFO;
// 内部クラス/グローバルクラスの継承
class MyException extends \Exception {}
?>
例4 名前空間内のクラス、関数あるいは定数へのアクセス
<?php
namespace foo;
class MyClass {}
// 現在の名前空間のクラスをタイプヒントに使用する方法
function test(MyClass $typehintexample = null) {}
// 現在の名前空間のクラスをタイプヒントに使用するもうひとつの方法
function test(\foo\MyClass $typehintexample = null) {}
// 現在の名前空間のクラスの継承
class Extended extends MyClass {}
// グローバル関数へのアクセス
$a = \globalfunc();
// グローバル定数へのアクセス
$b = \INI_ALL;
?>
\ から始まる名前は常に見た目のままに解釈されます。 つまり \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 のような名前は 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" の静的メソッド "name" をコールします
my\bar(); // "foo\my\bar" 関数をコールします
$a = my\BAR; // $a に定数 "foo\my\BAR" の値を設定します
?>
バックスラッシュを含まない name のようなクラス名は 2 通りの方法で解釈されます。
別の名前に name というエイリアスを指定する import 文がある場合は、そのエイリアスが適用されます。
それ以外の場合は、現在の名前空間が name の先頭に付け加えられます。
例7 非修飾クラス名
<?php
namespace foo;
use blah\blah as foo;
$a = new name(); // "foo\name" クラスのインスタンスを作成します
foo::name(); // "blah\blah" クラスの静的メソッド "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);
$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"
?>
The following script combinations are legal:
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; // instantiates class "thing" from namespace another
?>
There is no name conflict, even though the class MyClass exists within the my\stuff namespace, because the MyClass definition is in a separate file. However, the next example causes a fatal error on name conflict because MyClass is defined in the same file as the use statement.
<?php
namespace my\stuff;
use another\thing as MyClass;
class MyClass {} // fatal error: MyClass conflicts with import statement
$a = new MyClass;
?>
PHP does not allow nesting namespaces
<?php
namespace my\stuff {
namespace nested {
class foo {}
}
}
?>
However, it is easy to simulate nested namespaces like so:
<?php
namespace my\stuff\nested {
class foo {}
}
?>
The only elements that are affected by use statements are namespaces and class names. In order to shorten a long constant or function, import its containing namespace
<?php
namespace mine;
use ultra\long\ns\name;
$a = name\CONSTANT;
name\func();
?>
It is very important to realize that because the backslash is used as an escape character within strings, it should always be doubled when used inside a string. Otherwise there is a risk of unintended consequences:
例9 Dangers of using namespaced names inside a double-quoted string
<?php
$a = new "dangerous\name"; // \n is a newline inside double quoted strings!
$obj = new $a;
$a = new 'not\at\all\dangerous'; // no problems here.
$obj = new $a;
?>
Inside a single-quoted string, the backslash escape sequence is much safer to use, but it is still recommended practice to escape backslashes in all strings as a best practice.
Any undefined constant that is unqualified like FOO will produce a notice explaining that PHP assumed FOO was the value of the constant. Any constant, qualified or fully qualified, that contains a backslash will produce a fatal error if not found.
例10 Undefined constants
<?php
namespace bar;
$a = FOO; // produces 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
?>
Any attempt to define a namespaced constant that is a special, built-in constant results in a fatal error
例11 Undefined constants
<?php
namespace bar;
const NULL = 0; // fatal error;
const true = 'stupid'; // also fatal error;
// etc.
?>