引用命名空间标识符的三种方式
(1)Fully-qualified name
类似于操作系统上的绝对路径,而且是完整的路径,所以在理解的时候不会有误解。
比如在 new \A\B\C ,那么 C 就被会解析到 A\B 命名空间下的 C 类。
(2)Qualified name
类似于操作系统上的相对路径,它包含部分名字并被引用到当前的命名空间。
比如 B\C() 在命名空间 A 下调用,则最终引用的命名空间就是 A\B\C()。
(3)Unqualified name
类似于Qualified name,但是没包括子命名空间。比如 C() 在命名空间 A\B 下调用,则最终引用的命名空间就是 A\B\C()。
通过一个例子来说明三种引用方式:
namespace \Example;
require_once "function.php";
class ClassA {}
function Function() {}
//完全限定名称
\Example\Function();
\Example\B\Function();
//限定名称
B\Function(); //指向 \Example\B\Function();
//非限定名称
$test = new ClassA(); //resolves to \Example\ClassA
Function(); //指向 \Example\Function
注意:
Inside a namespace,假如在 current scope 没有发现函数和常量的定义,PHP 不会报错。而是去全局命名空间中寻找。
Inside a namespace,假如在 current scope 没有发现类的定义,则 PHP 会直接报错,不会去全局域中找对应的类,所以假如你需要引用一个 internal 或用户自定义的类,必须使用完全限定名称。
先举个简单的例子,首先编写一段代码(定义在命名空间下),命名为 function.php :
namespace Foo\Bar\subnamespace;
const FOO = 1;
function foo()
{
return "foo\r\n";
}
class foo
{
static function staticmethod()
{
return __METHOD__ . "\r\n" ;
}
function foofunction()
{
return __METHOD__ . "\r\n" ;
}
}
再编写一段代码 test.php,也是处于命名空间之下的代码:
namespace secondsp;
include 'function.php';
class foo
{
function foofunction()
{
return __METHOD__ . "\r\n" ;
}
}
function is_file($file)
{
return true ;
}
//非限定名称:实例化secondsp\foo类对象
$obj = new foo;
echo $obj->foofunction();
//实例化Foo\Bar\subnamespace\foo 类对象
$obj = new Foo\Bar\subnamespace\foo ;
echo $obj->foofunction();
//代码会报错,在命名空间内部,假如无法找到当前命名空间下的类,则会报错
//$obj = new ArrayObject(array(1));
$obj = new \ArrayObject(array(1));
//在命名空间内部,假如无法找到当前命名空间下的函数或者常量,则会寻找 native function
echo strlen("nihao");
//引用当前命名空间下的函数
var_dump(is_file('nihao')); //True
//引用全局函数
var_dump(\is_file('nihao')); //False
导入,别名
假如要使用的命名空间层级很长且数量很多,那么在使用的时候特别麻烦,所以可以使用 use 关键字导入命名空间、类、常量、函数等,然后可以使用它们直接引用完整的名称。而 alias 关键字可以给导入的类和函数等重命名。
举个例子如何使用 use 关键字,该代码处于全局命名空间之下:
include 'function.php';
use Foo\Bar\subnamespace\foo ;
$obj = new foo;
echo $obj->foofunction();
use Foo\Bar\subnamespace\foo as aliasfunname;
$obj = new aliasfunname;
echo $obj->foofunction();
use Foo\Bar\subnamespace ;
$obj = new subnamespace\foo ;
echo $obj->foofunction();
use Foo\Bar\subnamespace as aliasname;
$obj = new aliasname\foo ;
echo $obj->foofunction();
//由于调用代码并不在命名空间内,所以对于全局的类,无需引入使用
$obj = new ArrayObject(array(1));
//导入一个函数
use function Foo\Bar\subnamespace\foo ;
echo foo();
use function Foo\Bar\subnamespace\foo as func;
echo func();
use const Foo\Bar\subnamespace\FOO;
//echo FOO;