原文地址:https://www.sitepoint.com/php-53-namespaces-basics/
命名空间是php5.3的一个标志性改变,他很接近C#和Java,看起来能对php应用的结构带来更好的改变。
1.为什么我们需要命名空间?
伴随着你php代码量的增加,某个function或者class name可能被声明过。并且在引入第三方组件的时候,这个问题被放大了。好比有好多的的代码去实现数据库类怎么办?
知道现在,唯一的解决方案是加长你的class/function名字。举个例子Wordpress在每个名字前加了前缀'wp_'。The Zend Framework使用完整描述名称这样的习俗,就像Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive这样子,超长。
命名空间就可以很好的解决命名冲突问题。php的constans,classes和functions能够在命名空间内自由的使用。
2.如何定义命名空间?
一般来说,一切的constant,class和function名称都被存放在全局空间,就像他们先于命名空间被支持一样。
在php文件的顶端,使用namespace关键字来定义命名空间。
他必须是第一句命令,任何php代码或者空行都不能在他前面(注释除外)。
<?php
//定义一个命名空间
namespace MyProject;
上面代码以下的部分都属于MyProject命名空间,不允许嵌套命名空间或者为相同的代码块定义2个或者多个命名空间(只有最后一个会被识别,前面的会被忽略)。然而你却可以定义不同的命名空间在同一个文件里。
<?php
namespace MyProject1;
//MyProject1命名空间
namespace MyProject2;
//MyProject2命名空间
//替代语法/不能和上面两个同时
namespace MyProject3{
//MyProject3命名空间
}
?>
上面单独写都是对的,1,2和3不能在一起。
<?php
namespace MyProject;
function output() {
# Output HTML page
echo 'HTML!';
}
namespace RSSLibrary;
function output(){
# Output RSS feed
echo 'RSS!';
}
这里有2个命名空间,我们发现他们的function的名字是一样的,这种定义在平常的php中是不允许的会报错,Cannot redeclare。但是在这里不同的命名空间下面。我们可以这样调用:
\MyProject\output();
\RSSLibrary\output();
不过,我还是强烈建议,一个文件只用一个命名空间。
下面举一些反例:
<?php
namespace a;
echo "I belong to namespace a";
namespace b {
echo "I'm from namespace b";
}
函数刚开始会判断代码中是否同时用了不带括号和带括号的形式,如果是这样的话,会抛出一个编译类型错误:Cannot mix bracketed namespace declarations with unbracketed namespace declaration.
<?php
namespace b {
namespace a{
echo "I belong to namespace a";
}
}
这个就是说不能嵌套 Namespace declarations cannot be nested
子命名空间
PHP允许定义一个命名空间 命名的分层。子命名空间用\分割开。
MyProject\SubName
MyProject\Database\MySQL
3.调用命名空间
在下面的php文件中,我们将定义constant,class和function的命名空间App\Lib1
lib1.php
<?php
// application library 1
namespace App\Lib1;
const MYCONST = 'App\Lib1\MYCONST';
function MyFunction() {
return __FUNCTION__;
}
class MyClass {
static function WhoAmI() {
return __METHOD__;
}
}
?>
调用的php文件在这里:
myapp.php
<?php
header('Content-type: text/plain');
require_once('lib1.php');
echo \App\Lib1\MYCONST . "\n";
echo \App\Lib1\MyFunction() . "\n";
echo \App\Lib1\MyClass::WhoAmI() . "\n";
?>
myapp.php中并没有定义命名空间,所以这些代码存在于全局空间。任何直接涉及到MYCONST,MyFunction()或者MyClass将失败因为他们存在于App\Lib1的命名空间。我们必须增加\App\Lib1这样的前缀来创建一个全限定的名称。下面是myapp.php打印的结果:
App\Lib1\MYCONST
App\Lib1\MyFunction
App\Lib1\MyClass::WhoAmI
全限定的名称明显变得很长,这样显得对于App-Lib1-MyClass这样的命名相比没有很多的好处。在第二篇文章中,我将讨论一些混淆的现象并仔细来看看php是如何定义命名空间名字的。