file1.php
<?php namespace FooBarsubnamespace; const FOO = 1; function foo() {} class foo { static function staticmethod() {} } ?>
file2.php
<?php namespace FooBar; include 'file1.php'; const FOO = 2; function foo() {} class foo { static function staticmethod() {} } /* 非限定名称 */ foo(); // 解析为函数 FooBarfoo foo::staticmethod(); // 解析为类 FooBarfoo的静态方法staticmethod。 echo FOO; // resolves to constant FooBarFOO /* 限定名称 */ subnamespacefoo(); // 解析为函数 FooBarsubnamespacefoo subnamespacefoo::staticmethod(); // 解析为类 FooBarsubnamespacefoo, // 以及类的方法 staticmethod echo subnamespaceFOO; // 解析为常量 FooBarsubnamespaceFOO /* 完全限定名称 */ FooBarfoo(); // 解析为函数 FooBarfoo FooBarfoo::staticmethod(); // 解析为类 FooBarfoo, 以及类的方法 staticmethod echo FooBarFOO; // 解析为常量 FooBarFOO ?>
在命名空间内部访问全局类、函数和常量:
<?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 ?>
命名空间和动态语言特征
PHP 命名空间的实现受到其语言自身的动态特征的影响。因此,如果要将下面的代码转换到命名空间中,动态访问元素。
//example.php <?php class classname { function __construct() { echo __METHOD__," "; } } function funcname() { echo __FUNCTION__," "; } const constname = "global"; $a = 'classname'; $obj = new $a; // prints classname::__construct $b = 'funcname'; $b(); // prints funcname echo constant('constname'), " "; // prints global ?>
<?php namespace namespacename; class classname { function __construct() { echo __METHOD__," "; } } function funcname() { echo __FUNCTION__," "; } const constname = "namespaced"; include 'example1.php';//全局命名空间和某个命名空间有相同类 函数 和 常量 分别区别访问 $a = 'classname'; $obj = new $a; // prints classname::__construct $b = 'funcname'; $b(); // prints funcname echo constant('constname'), " "; // prints global /* note that if using double quotes, "\namespacename\classname" must be used */ $a = ' amespacenameclassname'; $obj = new $a; // prints namespacenameclassname::__construct $a = 'namespacenameclassname'; $obj = new $a; // also prints namespacenameclassname::__construct $b = 'namespacenamefuncname'; $b(); // prints namespacenamefuncname $b = ' amespacenamefuncname'; $b(); // also prints namespacenamefuncname echo constant(' amespacenameconstname'), " "; // prints namespaced echo constant('namespacenameconstname'), " "; // also prints namespaced ?>
namespace关键字和__NAMESPACE__常量
<?php namespace MyProject; echo '"', __NAMESPACE__, '"'; // 输出 "MyProject" ?>
<?php echo '"', __NAMESPACE__, '"'; // 输出 "" ?>
使用__NAMESPACE__动态创建名称
<?php namespace MyProject; function get($classname) { $a = __NAMESPACE__ . '\' . $classname; return new $a; } ?>
关键字 namespace 可用来显式访问当前命名空间或子命名空间中的元素。它等价于类中的 self 操作符。
<?php namespace MyProject; use blahlah as mine; // see "Using namespaces: importing/aliasing" blahmine(); // calls function blahlahmine() namespacelahmine(); // calls function MyProjectlahmine() namespacefunc(); // calls function MyProjectfunc() namespacesubfunc(); // calls function MyProjectsubfunc() namespacecname::method(); // calls static method "method" of class MyProjectcname $a = new namespacesubcname(); // instantiates object of class MyProjectsubcname $b = namespaceCONSTANT; // assigns value of constant MyProjectCONSTANT to $b ?>
在PHP中,别名是通过操作符 use 来实现的. 下面是一个使用所有可能的三种导入方式的例子:
- 使用use操作符导入/使用别名
<?php namespace foo; use MyFullClassname as Another; // 下面的例子与 use MyFullNSname as NSname 相同 use MyFullNSname; // 导入一个全局类 use ArrayObject; $obj = new namespaceAnother; // 实例化 fooAnother 对象 $obj = new Another; // 实例化 MyFullClassname 对象 NSnamesubnsfunc(); // 调用函数 MyFullNSnamesubnsfunc $a = new ArrayObject(array(1)); // 实例化 ArrayObject 对象 // 如果不使用 "use ArrayObject" ,则实例化一个 fooArrayObject 对象 ?>
- 一行中包含多个use语句
<?php use MyFullClassname as Another, MyFullNSname; $obj = new Another; // 实例化 MyFullClassname 对象 NSnamesubnsfunc(); // 调用函数 MyFullNSnamesubnsfunc ?> <p>导入操作是在编译执行的,但动态的类名称、函数名称或常量名称则不是。</p> <ol> <li>导入和动态名称</li> </ol> <pre> <?php use MyFullClassname as Another, MyFullNSname; $obj = new Another; // 实例化一个 MyFullClassname 对象 $a = 'Another'; $obj = new $a; // 实际化一个 Another 对象 ?>
- 导入和动态名称
<?php use MyFullClassname as Another, MyFullNSname; $obj = new Another; // 实例化一个 MyFullClassname 对象 $a = 'Another'; $obj = new $a; // 实际化一个 Another 对象 ?>
另外,导入操作只影响非限定名称和限定名称。完全限定名称由于是确定的,故不受导入的影响。
- 导入和完全限定名称
<?php use MyFullClassname as Another, MyFullNSname; $obj = new Another; // instantiates object of class MyFullClassname $obj = new Another; // instantiates object of class Another $obj = new Another hing; // instantiates object of class MyFullClassname hing $obj = new Another hing; // instantiates object of class Another hing ?>
使用命名空间:后备全局函数/常量
在一个命名空间中,当 PHP 遇到一个非限定的类、函数或常量名称时,它使用不同的优先策略来解析该名称。
- 类名称总是解析到当前命名空间中的名称(找不到就报错咯) 。因此在访问系统内部或不包含在命名空间中的类名称时,必须使用完全限定名称
- 函数和常量来说,如果当前命名空间中不存在该函数或常量,PHP 会退而使用全局空间中的函数或常量。
<?php namespace ABC; class Exception extends Exception {} $a = new Exception('hi'); // $a 是类 ABCException 的一个对象 $b = new Exception('hi'); // $b 是类 Exception 的一个对象 $c = new ArrayObject; // 致命错误, 找不到 ABCArrayObject 类 ?>
全局空间
如果没有定义任何命名空间,所有的类与函数的定义都是在全局空间,与 PHP 引入命名空间概念前一样。在名称前加上前缀 表示该名称是全局空间中的名称,即使该名称位于其它的命名空间中时也是如此。
<?php namespace ABC; /* 这个函数是 ABCfopen */ function fopen() { /* ... */ $f = fopen(...); // 调用全局的fopen函数 return $f; } ?>