名前空間は、ユーザーが作成したコードと PHP の内部クラス/関数/定数またはサードパーティのクラス/関数/定数の間の名前の競合を解決するために使用されます。ソース コードの読みやすさを向上させるために、非常に長い識別子名のエイリアス (または短い) 名を作成します。
任意の合法的な PHP コードを名前空間に含めることができますが、名前空間の影響を受けるのはクラス (抽象クラスと特性を含む)、インターフェイス、関数、定数のタイプのコードのみです。
ファイルに名前空間が含まれている場合は、declare キーワード、ソース ファイルのエンコード方法を定義するために使用される declare ステートメントを除き、他のすべてのコードよりも前に名前空間を宣言する必要があります。空白を含むコードを名前空間宣言の前に置くことはできません。
他の PHP 言語機能とは異なり、同じ名前空間を複数のファイルで定義できるため、同じ名前空間の内容を分割して異なるファイルに保存できます。
<?phpnamespace MyProject\Sub\Level;const CONNECT_OK = 1;class Connection { /* ... */ }function connect() {/* ... */ }
<?phpnamespace MyProject;const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */ }namespace AnotherProject;const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */ }
この構文を使用して 1 つのファイル内で複数の名前空間を定義することはお勧めできません。次の中括弧形式の構文を使用することをお勧めします。
<?phpnamespace MyProject {const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */ } }namespace AnotherProject {const CONNECT_OK = 1;class Connection { /* ... */ }function connect() { /* ... */ } }
実際のプログラミングの実践では、同じファイル内で複数の名前空間を定義することは強くお勧めできません。この方法は主に、同じファイル内の複数の PHP スクリプトを結合するために使用されます。
グローバル非名前空間のコードを名前空間のコードと組み合わせるには、中括弧の形式でのみ構文を使用できます。グローバル コードは、名前のない名前空間ステートメントを中括弧で囲む必要があります。
非修飾名、または $ などの接頭辞を含まないクラス名という 3 つの方法で参照できます。 =new foo(); または foo::staticmethod();。現在の名前空間が currentnamespace の場合、foo は currentnamespacefoo に解決されます。 foo を使用するコードがグローバルであり、どの名前空間にもコードが含まれていない場合、foo は foo として解決されます。 警告: 名前空間内の関数または定数が未定義の場合、修飾されていない関数または定数名はグローバル関数または定数名に解決されます。
修飾名、または接頭辞を含む名前 ($a = new subnamespacefoo(); や subnamespacefoo::staticmethod(); など)。現在の名前空間が currentnamespace の場合、foo は currentnamespacesubnamespacefoo に解決されます。 foo を使用するコードがグローバルであり、どの名前空間にも含まれていないコードの場合、foo は subnamespacefoo として解決されます。
完全修飾名、またはグローバル接頭辞演算子を含む名前 (例: $a = new currentnamespacefoo(); または currentnamespacefoo::staticmethod();)。この場合、foo は常にコード currentnamespacefoo 内のリテラル名に解決されます。
グローバル クラス、関数、定数にアクセスするには、strlen()、Exception、INI_ALL などの完全修飾名を使用できることに注意してください。
PHP は、現在の名前空間内の要素にアクセスする 2 つの抽象メソッド、__NAMESPACE__
マジック定数と __NAMESPACE__
魔术常量和namespace关键字。
__NAMESPACE__
namespace
__NAMESPACE__
は文字列を表すことができ、その他は namespace と同じです。
エイリアスをインポート/使用するには use 演算子を使用します
<?phpnamespace foo;use My\Full\Classname as Another;// 下面的例子与 use My\Full\NSname as NSname 相同use My\Full\NSname;// 导入一个全局类use ArrayObject;// importing a function (PHP 5.6+)use function My\Full\functionName;// aliasing a function (PHP 5.6+)use function My\Full\functionName as func;// importing a constant (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(); // calls function My\Full\functionNameecho CONSTANT; // echoes the value of My\Full
use 演算子を使用してエイリアスをインポート/使用します。複数の use ステートメントが 1 行に含まれます
<?phpuse My\Full\Classname as Another, My\Full\NSname;$obj = new Another; // 实例化 My\Full\Classname 对象NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func
インポート名と動的名
インポート操作は実行可能ファイルをコンパイルしていますが、動的クラス名、関数名、または定数名はコンパイルしていません。
<?phpuse My\Full\Classname as Another, My\Full\NSname;$obj = new Another; // 实例化一个 My\Full\Classname 对象$a = 'Another';$obj = new $a; // 实际化一个 Another 对象
インポートと完全修飾名
インポート操作は、非修飾名と修飾名のみに影響します。完全修飾名は決定的であるため、インポートの影響を受けません。<?phpuse My\Full\Classname as Another, My\Full\NSname;$obj = new Another; // instantiates object of class My\Full\Classname$obj = new \Another; // instantiates object of class Another$obj = new Another\thing; // instantiates object of class My\Full\Classname\thing$obj = new \Another\thing; // instantiates object of class Another\thing
<?phpnamespace A\B\C;/* 这个函数是 A\B\C\fopen */function fopen() { /* ... */ $f = \fopen(...); // 调用全局的fopen函数 return $f; }
<?phpnamespace 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; // 致命错误, 找不到 A\B\C\ArrayObject 类
<?phpnamespace 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_ALLecho strlen('hi'), "\n"; // 输出 "1"if (is_array('hi')) { // 输出 "is not array" echo "is array\n"; } else { echo "is not array\n"; }
在命名空间内部,所有的没有根据导入规则转换的限定名称均会在其前面加上当前的命名空间名称。例如,在命名空间 A\B 内部调用 C\D\e(),则 C\D\e() 会被转换为 A\B\C\D\e() 。
非限定类名根据当前的导入规则在编译时转换(用全名代替短的导入名称)。例如,如果命名空间 A\B\C 导入为C,则 new C() 被转换为 new A\B\C() 。
在命名空间内部(例如A\B),对非限定名称的函数调用是在运行时解析的。例如对函数 foo() 的调用是这样解析的:
在当前命名空间中查找名为 A\B\foo() 的函数
尝试查找并调用 全局(global) 空间中的函数 foo()。
在命名空间(例如A\B)内部对非限定名称或限定名称类(非完全限定名称)的调用是在运行时解析的。下面是调用 new C() 及 new D\E() 的解析过程: new C()的解析:
new D\E()的解析:
为了引用全局命名空间中的全局类,必须使用完全限定名称 new \C()。
在类名称前面加上当前命名空间名称变成:A\B\D\E,然后查找该类。
尝试自动装载类 A\B\D\E。
在当前命名空间中查找A\B\C类。
尝试自动装载类A\B\C。
<?phpnamespace A;use B\D, C\E as F;// 函数调用foo(); // 首先尝试调用定义在命名空间"A"中的函数foo() // 再尝试调用全局函数 "foo"\foo(); // 调用全局空间函数 "foo" my\foo(); // 调用定义在命名空间"A\my"中函数 "foo" F(); // 首先尝试调用定义在命名空间"A"中的函数 "F" // 再尝试调用全局函数 "F"// 类引用new B(); // 创建命名空间 "A" 中定义的类 "B" 的一个对象 // 如果未找到,则尝试自动装载类 "A\B"new D(); // 使用导入规则,创建命名空间 "B" 中定义的类 "D" 的一个对象 // 如果未找到,则尝试自动装载类 "B\D"new F(); // 使用导入规则,创建命名空间 "C" 中定义的类 "E" 的一个对象 // 如果未找到,则尝试自动装载类 "C\E"new \B(); // 创建定义在全局空间中的类 "B" 的一个对象 // 如果未发现,则尝试自动装载类 "B"new \D(); // 创建定义在全局空间中的类 "D" 的一个对象 // 如果未发现,则尝试自动装载类 "D"new \F(); // 创建定义在全局空间中的类 "F" 的一个对象 // 如果未发现,则尝试自动装载类 "F"// 调用另一个命名空间中的静态方法或命名空间函数B\foo(); // 调用命名空间 "A\B" 中函数 "foo"B::foo(); // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法 // 如果未找到类 "A\B" ,则尝试自动装载类 "A\B"D::foo(); // 使用导入规则,调用命名空间 "B" 中定义的类 "D" 的 "foo" 方法 // 如果类 "B\D" 未找到,则尝试自动装载类 "B\D"\B\foo(); // 调用命名空间 "B" 中的函数 "foo" \B::foo(); // 调用全局空间中的类 "B" 的 "foo" 方法 // 如果类 "B" 未找到,则尝试自动装载类 "B"// 当前命名空间中的静态方法或函数A\B::foo(); // 调用命名空间 "A\A" 中定义的类 "B" 的 "foo" 方法 // 如果类 "A\A\B" 未找到,则尝试自动装载类 "A\A\B"\A\B::foo(); // 调用命名空间 "A\B" 中定义的类 "B" 的 "foo" 方法 // 如果类 "A\B" 未找到,则尝试自动装载类 "A\B"?>
相关推荐:
以上がPHP名前空間を完全にマスターするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。