PHP Advanced Programming Study Notes 2014.06.12
Namespace Overview
PHP supports namespaces in versions after 5.3.0. What is a namespace? Broadly speaking, a namespace is a way of encapsulating things. This abstraction can be found in many places. In PHP, namespaces are used to solve two types of problems encountered when creating reusable code such as classes or functions when writing class libraries or applications:
PHP namespaces provide a way to group related classes, functions, and constants together. Here is an example illustrating PHP namespace syntax:
Define namespace
Although any legal PHP code can be included in a namespace, there are only three types of code affected by namespaces: classes, functions, and constants. Namespaces are declared using the keyword namespace. If a file contains a namespace, it must declare the namespace before all other code. In addition, unlike other language features of PHP, the same namespace can be defined in multiple files, which allows the contents of the same namespace to be divided and stored in different files. Of course you can also define multiple namespaces in the same file.
<span>namespace</span><span> MyProject; </span><span>class</span><span> MyClass { #code... }</span>
Define sub-namespaces: Much like the relationship between directories and files, PHP namespaces also allow you to specify hierarchical namespace names. Therefore, namespace names can be defined in a hierarchical manner:
<span>namespace</span><span> MyProject\helper\http; </span><span>class</span><span> MyClass { #code... }</span>
Defining multiple namespaces in the same file: There are two ways to declare multiple namespaces in the same file, but in actual programming practice, it is highly discouraged to declare multiple namespaces in the same file. Define the Dogo namespace. This method is mainly used to combine multiple PHP scripts in the same file. The first method is listed below.
<span>namespace</span><span> MyProject\helper\http; </span><span>class</span><span> MyClass { #code... } </span><span>namespace</span><span> MyProject\helper\request; </span><span>class</span><span> MyClass { #code... }</span>
However, it is strongly not recommended to use this method. You can refer to the following brace definition method:
<span>namespace</span><span> MyProject\helper\http; { </span><span>class</span><span> MyClass { #code... } } </span><span>namespace</span><span> MyProject\helper\request; { </span><span>class</span><span> MyClass { #code... } }</span>
Elements in the PHP namespace use
Before discussing how to use namespaces, you must understand how PHP knows which namespace elements to use. Class names can be referenced in three ways:
Use namespace: alias/import
Allowing external fully qualified names to be referenced or imported via aliases is an important feature of namespaces. PHP namespace support There are two ways to use aliases or imports: using aliases for class names, or using aliases for namespace names. In PHP, aliases are implemented through the operator use.
Note that PHP does not support imported functions or constants.
<span>namespace</span><span> foo; use My\Full\Classname </span><span>as</span><span> Another; </span><span>//</span><span> 下面的例子与 use My\Full\NSname as NSname 相同</span> <span>use My\Full\NSname; </span><span>//</span><span> 导入一个全局类</span> use \ArrayObject;
Name resolution rules
Before explaining the name resolution rules, let’s look at some important definitions:
Name resolution follows the following rules:
Example name resolution example
<?<span>php namespace A; </span><span>use</span> B\D, C\E <span>as</span><span> F; </span><span>//</span><span> 函数调用</span> <span> foo(); </span><span>//</span><span> 首先尝试调用定义在命名空间"A"中的函数foo() // 再尝试调用全局函数 "foo"</span> <span> \foo(); </span><span>//</span><span> 调用全局空间函数 "foo" </span> <span> my\foo(); </span><span>//</span><span> 调用定义在命名空间"A\my"中函数 "foo" </span> <span> F(); </span><span>//</span><span> 首先尝试调用定义在命名空间"A"中的函数 "F" // 再尝试调用全局函数 "F" // 类引用</span> <span>new</span> B(); <span>//</span><span> 创建命名空间 "A" 中定义的类 "B" 的一个对象 // 如果未找到,则尝试自动装载类 "A\B"</span> <span>new</span> D(); <span>//</span><span> 使用导入规则,创建命名空间 "B" 中定义的类 "D" 的一个对象 // 如果未找到,则尝试自动装载类 "B\D"</span> <span>new</span> F(); <span>//</span><span> 使用导入规则,创建命名空间 "C" 中定义的类 "E" 的一个对象 // 如果未找到,则尝试自动装载类 "C\E"</span> <span>new</span> \B(); <span>//</span><span> 创建定义在全局空间中的类 "B" 的一个对象 // 如果未发现,则尝试自动装载类 "B"</span> <span>new</span> \D(); <span>//</span><span> 创建定义在全局空间中的类 "D" 的一个对象 // 如果未发现,则尝试自动装载类 "D"</span> <span>new</span> \F(); <span>//</span><span> 创建定义在全局空间中的类 "F" 的一个对象 // 如果未发现,则尝试自动装载类 "F" // 调用另一个命名空间中的静态方法或命名空间函数</span> <span> B\foo(); </span><span>//</span><span> 调用命名空间 "A\B" 中函数 "foo"</span> <span> B</span>::foo(); <span>//</span><span> 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法 // 如果未找到类 "A\B" ,则尝试自动装载类 "A\B"</span> <span> D</span>::foo(); <span>//</span><span> 使用导入规则,调用命名空间 "B" 中定义的类 "D" 的 "foo" 方法 // 如果类 "B\D" 未找到,则尝试自动装载类 "B\D"</span> <span> \B\foo(); </span><span>//</span><span> 调用命名空间 "B" 中的函数 "foo" </span> <span> \B</span>::foo(); <span>//</span><span> 调用全局空间中的类 "B" 的 "foo" 方法 // 如果类 "B" 未找到,则尝试自动装载类 "B" // 当前命名空间中的静态方法或函数</span> <span> A\B</span>::foo(); <span>//</span><span> 调用命名空间 "A\A" 中定义的类 "B" 的 "foo" 方法 // 如果类 "A\A\B" 未找到,则尝试自动装载类 "A\A\B"</span> <span> \A\B</span>::foo(); <span>//</span><span> 调用命名空间 "A\B" 中定义的类 "B" 的 "foo" 方法 // 如果类 "A\B" 未找到,则尝试自动装载类 "A\B"</span> ?>