Latest web development tutorials

PHP namespace (namespace)

PHP namespace (namespace) is added in PHP 5.3, if you learned C # and Java, namespace that is not anything new things. But in PHP which still has a very important significance.

PHP namespaces can solve the following two problems:

  1. User-written code inside PHP classes / functions / constants or third-party classes / functions / constants name conflicts between.
  2. As long identifier names (usually to alleviate the first category defined) create an alias (or short) the name of improving the readability of source code.

Defining namespaces

By default, all constants, classes, and function names are placed in the global space, just the same as before the namespace support PHP.

Namespace declaration by keyword namespace. If a file name contains spaces, it must declare the namespace before any other code. Syntax is as follows;

< ?php  
// 定义代码在 'MyProject' 命名空间中  
namespace MyProject;  
 
// ... 代码 ...  

You can also define different namespaces in the same file in the code, such as:

< ?php  
namespace MyProject1;  
// MyProject1 命名空间中的PHP代码  
 
namespace MyProject2;  
// MyProject2 命名空间中的PHP代码    
 
// 另一种语法
namespace MyProject3 {  
 // MyProject3 命名空间中的PHP代码    
}  
?>  

Before declaring a namespace unique legal code is used to define the source file encoding methods declare statement. All non-PHP code includes whitespace can not appear before the namespace declaration.

<?php
declare(encoding='UTF-8'); //定义多个命名空间和不包含在命名空间中的代码
namespace MyProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace { // 全局代码
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>

The following code syntax error will occur:

<html>
<?php
namespace MyProject; // 命名空间前出现了“<html>” 会致命错误 - 命名空间必须是程序脚本的第一条语句
?>

Subnamespaces

Relationship with directories and files much like, PHP namespaces also allows to specify the name of the hierarchical namespace. Thus, the name of the namespace can be defined using a hierarchical manner:

<?php
namespace MyProject\Sub\Level;  //声明分层次的单个命名空间

const CONNECT_OK = 1;
class Connection { /* ... */ }
function Connect() { /* ... */  }

?>

The above example creates constant MyProject \ Sub \ Level \ CONNECT_OK, type MyProject \ Sub \ Level \ Connection and function MyProject \ Sub \ Level \ Connect.


Namespaces

PHP namespace class name can be referenced in three ways:

  1. Unqualified name, or the name of the class does not contain a prefix, such as $ a = new foo (); or foo :: staticmethod () ;. If the current namespace is currentnamespace, foo will be interpreted as currentnamespace \ foo. If foo is global code, the code does not contain any namespace, it will be parsed as foo foo. Warning: If the namespace function or constant is not defined, then the function name or unqualified constant name will be resolved to the global function name, or constant name.

  2. Qualified name, or the name contains the prefix, such as $ a = new subnamespace \ foo ( ); or subnamespace \ foo :: staticmethod () ;. If the current namespace is currentnamespace, then foo will be parsed as currentnamespace \ subnamespace \ foo. If foo is global code, the code does not contain any namespace, foo will be resolved to subnamespace \ foo.

  3. Fully qualified name, or include a global prefix operator name, for example, $ a = new \ currentnamespace \ foo (); or \ currentnamespace \ foo :: staticmethod () ;. In this case, foo will always be resolved to the name of the code words (literal name) currentnamespace \ foo.

Here is an instance of these three ways:

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() {}
}

/* 非限定名称 */
foo(); // 解析为 Foo\Bar\foo resolves to function Foo\Bar\foo
foo::staticmethod(); // 解析为类 Foo\Bar\foo的静态方法staticmethod。resolves to class Foo\Bar\foo, method staticmethod
echo FOO; // resolves to constant Foo\Bar\FOO

/* 限定名称 */
subnamespace\foo(); // 解析为函数 Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // 解析为类 Foo\Bar\subnamespace\foo,
                                  // 以及类的方法 staticmethod
echo subnamespace\FOO; // 解析为常量 Foo\Bar\subnamespace\FOO
                                  
/* 完全限定名称 */
\Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // 解析为类 Foo\Bar\foo, 以及类的方法 staticmethod
echo \Foo\Bar\FOO; // 解析为常量 Foo\Bar\FOO
?>

Note that to access any global class, function or constant, you can use the fully qualified name, such as \ strlen () or \ Exception or \ INI_ALL.

Namespace Accessing global classes, functions and constants:

<?php
namespace Foo;

function strlen() {}
const INI_ALL = 3;
class Exception {}

$a = \strlen('hi'); // 调用全局函数strlen
$b = \INI_ALL; // 访问全局常量 INI_ALL
$c = new \Exception('error'); // 实例化全局类 Exception
?>

Namespaces and dynamic language features

Implement PHP namespace affected by its own dynamic language features. So, if you want the following code into namespaces, dynamic access 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
?>

You must use a fully qualified name (including the class name of the namespace prefix). Note that because in a dynamic class name, function name, or constant name, qualified name and the fully qualified name is no difference, so the leading backslash is unnecessary.

Dynamic Access namespace element

<?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; // prints classname::__construct
$b = 'funcname';
$b(); // prints funcname
echo constant('constname'), "\n"; // prints global

/* note that if using double quotes, "\\namespacename\\classname" must be used */
$a = '\namespacename\classname';
$obj = new $a; // prints namespacename\classname::__construct
$a = 'namespacename\classname';
$obj = new $a; // also prints namespacename\classname::__construct
$b = 'namespacename\funcname';
$b(); // prints namespacename\funcname
$b = '\namespacename\funcname';
$b(); // also prints namespacename\funcname
echo constant('\namespacename\constname'), "\n"; // prints namespaced
echo constant('namespacename\constname'), "\n"; // also prints namespaced
?>

namespace keyword and constants __NAMESPACE__

PHP supports two ways to access the current namespace abstract interior elements, __ NAMESPACE__ Magic constants and namespace keyword.

__NAMESPACE__ Constant value is a string containing the name of the current namespace. In global, the code does not include any namespace that contains an empty string.

__NAMESPACE__ Example, in a namespace code

<?php
namespace MyProject;

echo '"', __NAMESPACE__, '"'; // 输出 "MyProject"
?>

__NAMESPACE__ Example, global code

<?php

echo '"', __NAMESPACE__, '"'; // 输出 ""
?>

Constant __NAMESPACE__ created dynamically when the name is useful, for example:

Use __NAMESPACE__ dynamically created name

<?php
namespace MyProject;

function get($classname)
{
    $a = __NAMESPACE__ . '\\' . $classname;
    return new $a;
}
?>

Namespace keyword can be used to explicitly access the current namespace or a sub-namespace elements. It is equivalent to the class of self operator.

namespace operator namespace code

<?php
namespace MyProject;

use blah\blah as mine; // see "Using namespaces: importing/aliasing"

blah\mine(); // calls function blah\blah\mine()
namespace\blah\mine(); // calls function MyProject\blah\mine()

namespace\func(); // calls function MyProject\func()
namespace\sub\func(); // calls function MyProject\sub\func()
namespace\cname::method(); // calls static method "method" of class MyProject\cname
$a = new namespace\sub\cname(); // instantiates object of class MyProject\sub\cname
$b = namespace\CONSTANT; // assigns 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 object of class sub\cname
$b = namespace\CONSTANT; // assigns value of constant CONSTANT to $b
?>

Using namespaces: Aliasing / Importing

PHP namespaces support two using aliases or importing: Use an alias for the class name, or an alias for a namespace name. Note that PHP does not support importing a function or constant.

In PHP, alias for operator use to achieve the following is a use of all possible ways to import three examples:

1, using the use operator import / alias

<?php
namespace foo;
use My\Full\Classname as Another;

// 下面的例子与 use My\Full\NSname as NSname 相同
use My\Full\NSname;

// 导入一个全局类
use \ArrayObject;

$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 对象
?>

2, the line that contains multiple use statements

<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // 实例化 My\Full\Classname 对象
NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func
?>

Import operation is performed at compile time, but a dynamic class name, function name, or constant name is not.

3, Import and dynamic name

<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // 实例化一个 My\Full\Classname 对象
$a = 'Another';
$obj = new $a;      // 实际化一个 Another 对象
?>

In addition, the import operation only affects unqualified and qualified names. Fully qualified name because it is identified, it is not affected by the import.

4, Importing and fully qualified names

<?php
use 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
?>

Using namespaces: fallback to global function / constant

In a namespace, when PHP encounters a unqualified class, function or constant name, it uses a different priority strategies to resolve the name. The class name of the current namespace name always resolves to. Therefore, in an internal access to the system or not included in the namespace of the class name, you must use the fully qualified name, for example:

1, access global classes in a namespace

<?php
namespace 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 类
?>

For functions and constants, the function does not exist or if the current namespace constants, PHP will fall back to global functions or constants in space.

2, global function namespace reserved / constants

<?php
namespace 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_ALL

echo strlen('hi'), "\n"; // 输出 "1"
if (is_array('hi')) { // 输出 "is not array"
    echo "is array\n";
} else {
    echo "is not array\n";
}
?>

Global space

If you do not define any namespace, all class definitions and functions are in a global space and PHP as before the introduction of the concept of namespaces. Before the name prefixed \ indicates that the name is a global name space, it is also true of other namespace even if the name is located.

Description Use global space

<?php
namespace A\B\C;

/* 这个函数是 A\B\C\fopen */
function fopen() { 
     /* ... */
     $f = \fopen(...); // 调用全局的fopen函数
     return $f;
} 
?>

Order namespace

Since with the namespace, which is the most error-prone use of class time, to find the path of this class is what the.

<?php
namespace 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"
?>

Name Resolution Follow these rules:

  1. Function fully qualified name of the class and the constant calls resolved at compile time. For example new \ A \ B resolves to class A \ B.
  2. All unqualified and qualified names (not fully qualified names) converted at compile time based on current import rules. For example, if the namespace A \ B \ C is imported as C, then a call to C \ D \ e () will be converted to A \ B \ C \ D \ e ().
  3. Namespace inside, all qualified names not translated according to import rules will be added to the current namespace name in front of it. For example, in the namespace A \ B Internal call C \ D \ e (), then C \ D \ e () is translated to A \ B \ C \ D \ e ().
  4. Non-qualified class name of the converter (with full name instead of the name of a short introduction) at compile time based on current import rules. For example, if the namespace A \ B \ C is imported as C, the new C () are converted to new A \ B \ C () .
  5. Namespace internal (such as A \ B), calls to unqualified function name is resolved at runtime. For example, a call to function foo () is resolved like this:
    1. Find called A \ B \ foo in the current namespace () function
    2. Try to find and call the global (global) space function foo ().
  6. Namespace (for example, A \ B) internal to unqualified or qualified name of the class names (not fully qualified names) call is resolved at run time. Here is the call to new C () and the new D \ E () of the resolution process: new C () parsing:
    1. Find A \ B \ C class in the current namespace.
    2. It attempts to autoload A \ B \ C.
    new D \ E () parsing:
    1. In the class name preceded by the current namespace name becomes: A \ B \ D \ E , then look for the class.
    2. It attempts to autoload A \ B \ D \ E.
    To reference the global namespace global class, you must use the fully qualified name new \ C ().