English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
PHP namespaces (namespace) are in PHP 5.3is added, if you have learned C# and Java, then namespaces are not a new thing. However, they still have great significance in PHP.
PHP namespaces can solve the following two types of problems:
User-written code versus PHP internal classes/Functions/Constants or third-party classes/Functions/Name conflicts between constants
Create an alias (or a short) name for a long identifier name (usually to mitigate the first-class problem), which improves the readability of the source code.
By default, all constants, class, and function names are placed in the global scope, just as PHP supported namespaces before.
Namespaces are declared using the keyword namespace. If a file contains a namespace, it must declare the namespace before any other code. The syntax format is as follows;
<?php // Define code within the 'MyProject' namespace 命名空间MyProject; // ... code ...
You can also define different namespace code within the same file, like:
<?php 命名空间MyProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } namespace AnotherProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } ?>
It is not recommended to define multiple namespaces within a single file using this syntax. It is suggested to use the following syntax with curly braces.
<?php namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace AnotherProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } ?>
Combining code from a global, non-namespaced scope with code from a namespaced scope can only be done using the syntax with curly braces. Global code must be enclosed within curly braces using a namespace statement without a name, for example:
<?php namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace { // Global code session_start(); $a = MyProject\connect(); echo MyProject\Connection::start(); } ?>
The only valid code before declaring a namespace is the declare statement used to define the encoding of the source file. No non-PHP code, including whitespace, can appear before the declaration of a namespace.
<?php declare(encoding='UTF-8')-8'); //Define multiple namespaces and code not included in the namespace namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace { // Global code session_start(); $a = MyProject\connect(); echo MyProject\Connection::start(); } ?>
The following code will result in a syntax error:
<html> <?php 命名空间MyProject; // A fatal error will occur if "<html>" appears before the namespace - The namespace must be the first statement in the program script ?>
Similar to the relationship between directories and files, PHP namespaces also allow specifying the name of a hierarchical namespace. Therefore, the namespace name can be defined in a hierarchical manner:
<?php namespace MyProject\Sub\Level; //Declare a hierarchical single namespace const CONNECT_OK = 1; class Connection { /* ... */ } function Connect() { /* ... */ } ?>
The above example creates the constant MyProject\Sub\Level\CONNECT_OK, the class MyProject\Sub\Level\Connection, and the function MyProject\Sub\Level\Connect.
The class name in a PHP namespace can be referenced in three ways:
Unqualified name, or a class name without a prefixFor example, $a = new foo(); or foo::staticmethod();. If the current namespace is currentnamespace, foo will be resolved as currentnamespace\foo. If the code using foo is global and does not contain any namespace, then foo will be resolved as foo. Warning: If a function or constant in the namespace is not defined, the non-qualified function name or constant name will be resolved as the global function name or constant name.
Qualified name, or a name with a prefixFor example, $a = new subnamespace\foo(); or subnamespace\foo::staticmethod();. If the current namespace is currentnamespace, foo will be resolved as currentnamespace\subnamespace\foo. If the code using foo is global and does not contain any namespace, foo will be resolved as subnamespace\foo.
Fully qualified name, or names that include the global prefix operator.For example, $a = new \currentnamespace\foo(); or \currentnamespace\foo::staticmethod();. In this case, foo is always parsed as the literal name currentnamespace\foo in the code.
Below is an example of using these three methods:
file1.php file code
<?php namespace Foo\Bar\subnamespace; const FOO = 1; function foo() {} class foo { static function staticmethod() {} } ?>
file2.php file code
<?php namespace Foo\Bar; include 'file1.php'; const FOO = 2; function foo() {} class foo { static function staticmethod() {} } /* Unqualified name */ foo(); // Parsed as function Foo\Bar\foo foo::staticmethod(); // Parsed as class Foo\Bar\foo, method staticmethod echo FOO; // Parsed as constant Foo\Bar\FOO /* Qualified name */ subnamespace\foo(); // Parsed as function Foo\Bar\subnamespace\foo subnamespace\foo::staticmethod(); // Parsed as class Foo\Bar\subnamespace\foo, // as well as class methods staticmethod echo subnamespace\FOO; // Parsed as constant Foo\Bar\subnamespace\FOO /* Fully qualified name */ \Foo\Bar\foo(); // Parsed as function Foo\Bar\foo \Foo\Bar\foo::staticmethod(); // Parsed as class Foo\Bar\foo, as well as class methods staticmethod echo \Foo\Bar\FOO; // Parsed as constant Foo\Bar\FOO ?>
Note that you can use fully qualified names to access any global class, function, or constant, for example \strlen() or \Exception or \INI_ALL.
Access global classes, functions, and constants within a namespace:
<?php namespace Foo; function strlen() {} const INI_ALL = 3; class Exception {} $a = \strlen('hi'); // Call the global function strlen $b = \INI_ALL; // Access the global constant INI_ALL $c = new \Exception('error'); // Example of a global class Exception ?>
The implementation of PHP namespaces is influenced by the dynamic features of the language itself. Therefore, if you want to convert the following code to a namespace, dynamically access the elements.
example1.php file code:
<?php class classname { function __construct() { echo __METHOD__, '\n'; } } function funcname() { echo __FUNCTION__, '\n'; } const constname = 'global'; $a = 'classname'; $obj = new $a; // prints classname::__construct $b = 'funcname'; $b(); // prints funcname echo constant('constname'), '\n'; // prints global ?>
It is necessary to use the fully qualified name (including the class name with the namespace prefix). Note that since there is no difference between the qualified name and the fully qualified name in the dynamic class name, function name, or constant name, the leading backslash is not necessary.
Dynamically access the elements of the namespace
<?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; // Output classname::__construct $b = 'funcname'; $b(); // Output function name echo constant('constname'), '\n'; // Output global /* If using double quotes, the method is "\\namespacename\\classname"*/ $a = '\namespacename\classname'; $obj = new $a; // Output namespacename\classname::__construct $a = 'namespacename\classname'; $obj = new $a; // Output 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 ?>
PHP支持两种抽象的访问当前命名空间内部元素的方法,__NAMESPACE__魔术常量和namespace关键字。
常量__NAMESPACE__的值是包含当前命名空间名称的字符串。在全局代码中,不包括在任何命名空间中的代码,它包含一个空字符串。
__NAMESPACE__示例,在命名空间中的代码
<?php 命名空间MyProject; echo '"', __NAMESPACE__, '"'; // 输出"MyProject" ?>
__NAMESPACE__示例,全局代码
<?php echo '"', __NAMESPACE__, '"'; // 输出"" ?>
常量__NAMESPACE__在动态创建名称时非常有用,例如:
使用__NAMESPACE__动态创建名称
<?php 命名空间MyProject; 函数get($classname) { $a = __NAMESPACE__ . '\' . $classname; 返回new $a; } ?>
关键字namespace可用于显式访问当前命名空间或子命名空间中的元素。它与类中的self操作符等价。
命名空间操作符,命名空间中的代码
<?php 命名空间MyProject; 使用blah\blah作为mine; // 参见"使用命名空间:导入"/别名" 执行blah\mine(); // 调用function blah\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; // Assigns the value of constant MyProject\CONSTANT to $b ?>
Namespace operator, global code
<?php namespace\func(); // Calls function func() namespace\sub\func(); // Calls function sub\func() namespace\cname::method(); // Calls static method 'method' of class cname $a = new namespace\sub\cname(); // Instantiates an object of class sub\cname $b = namespace\CONSTANT; // Assigns the value of constant CONSTANT to $b ?>
PHP namespace supports two ways to use aliases or import: alias for class names, or alias for namespace names.
In PHP, aliases are implemented by the use operator. Here is an example using all three possible import methods:
1Multiple use statements in one line/Use alias
<?php namespace foo; use My\Full\Classname as Another; // The following instance is the same as 'use My\Full\NSname as NSname' use My\Full\NSname; // Import a global class use \ArrayObject; $obj = new namespace\Another; // Example an 'foo\Another' object $obj = new Another; // Example a 'My\Full\Classname' object NSname\subns\func(); // Call function 'My\Full\NSname\subns\func' $a = new ArrayObject(array(1)); // Example an 'ArrayObject' object // If 'use \ArrayObject' is not used, an object of 'foo\ArrayObject' is instantiated ?>
2Multiple use statements in one line
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // Example a 'My\Full\Classname' object NSname\subns\func(); // Call function 'My\Full\NSname\subns\func' ?>
Import operations are compiled and executed, but dynamic class names, function names, or constant names are not.
3Import and dynamic names
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // Example a 'My\Full\Classname' object $a = 'Another'; $obj = new $a; // Actualize an Another object ?>
Additionally, the import operation only affects unqualified names and qualified names. Fully qualified names are determined and are not affected by the import.
4Importing and fully qualified names
<?php use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // Example of instantiating My\Full\Classname class $obj = new \Another; // Example of instantiating Another class $obj = new Another\thing; // Example of instantiating My\Full\Classname\thing class $obj = new \Another\thing; // Example of instantiating Another\thing class ?>
In a namespace, when PHP encounters an unqualified class, function, or constant name, it uses a different priority strategy to resolve the name. Class names are always resolved to the name in the current namespace. Therefore, when accessing system internal or class names not included in the namespace, the fully qualified name must be used, for example:
1Accessing global class in namespace
<?php namespace A\B\C; class Exception extends \Exception {} $a = new Exception('hi'); // $a is an object of the class A\B\C\Exception $b = new \Exception('hi'); // $b is an object of the class Exception $c = new ArrayObject; // Fatal error, cannot find A\B\C\ArrayObject class ?>
For functions and constants, if the function or constant does not exist in the current namespace, PHP will resort to using the function or constant in the global space.
2of the backup global function in the namespace/constant
<?php namespace A\B\C; const E_ERROR = 45; function strlen($str) { return \strlen($str) - 1; } echo E_ERROR, "\n" // echo ""45" echo INI_ALL, "\n" // echo ""7" - use global constant INI_ALL echo strlen('hi'), "\n" // echo ""1" if (is_array('hi')) { // echo "is not array" else { } echo "is not array\n"; } ?>
If no namespace is defined, all class and function definitions are in the global space, just like before the introduction of the namespace concept in PHP. Adding the prefix \ to the name indicates that the name is in the global space, even if the name is located in another namespace.
Use global space notation
<?php namespace A\B\C; /* This function is A\B\C\fopen */ function fopen() { /* ... */ $f = \fopen(...); // Call the global fopen function return $f; } ?>
Since the introduction of namespaces, the most likely error occurs when using classes, what is the search path for this class?
<?php namespace A; use B\D, C\E as F; // Function call foo(); // Firstly, try to call the function foo() defined in the namespace "A" // Try to call the global function "foo" again \foo(); // Call the global function "foo" my\foo(); // Call the function "foo" defined in the namespace "A\my" F(); // Firstly, try to call the function "F" defined in the namespace "A" // Try to call the global function "F" again // Class reference new B(); // Create an object of the class "B" defined in the namespace "A" // If not found, try to automatically load the class "A\B" new D(); // Using import rules, create an object of the class "D" defined in the namespace "B" // If not found, try to automatically load the class "B\D" new F(); // Using import rules, create an object of the class "E" defined in the namespace "C" // If not found, try to automatically load the class "C\E" new \B(); // Create an object of the class "B" defined in the global space // If not found, try to automatically load the class "B" new \D(); // Create an object of the class "D" defined in the global space // If not found, try to automatically load the class "D" new \F(); // Create an object of the class "F" defined in the global space // If not found, try to automatically load the class "F" // Call a static method or namespace function in another namespace B\foo(); // Call the function "foo" in the namespace "A\B" B::foo(); // Call the "foo" method of the class "B" defined in the namespace "A" // If the class "A\B" is not found, try to automatically load the class "A\B" D::foo(); // Using import rules, call the "foo" method of the class "D" defined in the namespace "B" // If the class "B\D" is not found, then try to automatically load the class "B\D" \B\foo(); // Call the function "foo" in the namespace "B" \B::foo(); // Call the "foo" method of the class "B" in the global space // If the class "B" is not found, then try to automatically load the class "B" // Static methods or functions in the current namespace A\B::foo(); // Call the "foo" method of the class "B" defined in the namespace "A\A" // If the class "A\A\B" is not found, then try to automatically load the class "A\A\B" \A\B::foo(); // Call the "foo" method of the class "B" defined in the namespace "A" // If the class "A\B" is not found, then try to automatically load the class "A\B" ?>
Name resolution follows the following rules:
The calls to functions, classes, and constants with fully qualified names are resolved at compile time. For example new \A\B is resolved as a class A\B.
All non-qualified names and qualified names (non-fully qualified names) are converted according to the current import rules at compile time. For example, if the namespace A\B\C is imported as C, then the call to C\D\e() the call is converted to A\B\C\D\e().
In the namespace, all qualified names that are not converted according to the import rules are prefixed with the current namespace name. For example, in the namespace A\B Internal call C\D\e(), then C\D\e() is converted to A\B\C\D\e() .
Non-qualified class names are converted according to the current import rules at compile time (using full names instead of short import names). For example, if the namespace A\B\C Imported as C, then new C() is converted to new A\B\C() .
Inside the namespace (for example A\B), the calls to non-qualified names of functions are resolved at runtime. For example, the call to the function foo() in the current namespace is parsed as follows:
Search for the name A\B\foo() the function
Attempt to find and call global(global) function in the space foo().
in the namespace (for exampleA\BThe calls to non-qualified names or qualified names of classes (non-fully qualified names) inside the scope are resolved at runtime. Below is the call new C() and new D\E() Parsing process: new C()Parsing: new D\E()Parsing: To reference the global class in the global namespace, it is necessary to use the fully qualified name new \C().
Add the current namespace name before the class name to become:A\B\D\E, then search for the class.
Attempt to automatically load class A\B\D\E.
Search within the current namespaceA\B\Cclass.
Attempt to automatically load classA\B\C.