日期:2011-06-27  浏览次数:20608 次

1. namespace:
 
    和C++中的名字空间很像,作用也一样,都是为了避免在引用较多第三方库时而带来的名字冲突问题。通过名字空间,即便两个class的名称相同,但是因为位于不同的名字空间内,他们仍然可以被精确定位和区分。第一次看到PHP的名字空间语法时,感觉和C++相比在语法上是非常非常相似的,然而在写点儿小例子做做实验的时候才发现,他们的差别还是很大的,为了避免以后忘记,所以这里特别将其记录了下来。见如下代码:
 
复制代码
<?php
//in Test2.php
namespace nstest\test2;
 
class Test2 {
    public static function printMe() {
        print 'This is nstest\test2\Test2::printSelf.'."\n";
    }
}
 
<?php
//in Test1.php
namespace nstest\test1;
 
class Test1 {
    public static function printMe() {
        print 'This is nstest\test1\Test1::printSelf.'."\n";
    }
}
require "Test2.php";
nstest\test2\Test2::printMe();
复制代码
    运行结果如下:
 
bogon:TestPhp$ php Test1.php 
PHP Fatal error:  Class 'nstest\test1\nstest\test2\Test2' not found in /Users/liulei/PhpstormProjects/TestPhp/Test1.php on line 13
    是不是这个结果比较出乎意料,原因在哪呢?HOHO,原来PHP在进行名字空间引用的时候,如果名字空间的第一个字符不是前导斜杠(\),那么就被自动识别为相对名字空间,在上面的代码中,Test1自身所在的名字空间是namespace nstest\test1,因此在以nstest\test2\Test2::printMe()方式调用Test2::printMe()时,PHP将自动解析为nstest\test1\nstest\test2\Test2::printMe(),即认为nstest\test2是在当前名字空间内部的。修正该问题非常简单,只需在引用时加上前导斜杠(\)即可,见以下修复后的代码:     
 
复制代码
<?php
//Test2.php
namespace nstest\test2;
 
class Test2 {
    public static function printMe() {
        print 'This is nstest\test2\Test2::printSelf.'."\n";
    }
}
 
<?php
//Test1.php
namespace nstest\test1;
 
class Test1 {
    public static function printMe() {
        print 'This is nstest\test1\Test1::printSelf.'."\n";
    }
}
require "Test2.php";
\nstest\test2\Test2::printMe();
复制代码
    运行结果如下:
 
bogon:TestPhp$ php Test1.php 
This is nstest\test2\Test2::printSelf.
    还有一种改动方式,可以示意一下PHP中名字空间中的相对引用。这里我们可以将Test1的名字空间改为namespace nstest,其他的修改见以下代码中红色高亮部分:
 
复制代码
<?php
//Test2.php
namespace nstest\test2;
 
class Test2 {
    public static function printMe() {
        print 'This is nstest\test2\Test2::printSelf.'."\n";
    }
}
 
<?php
//Test1.php
namespace nstest;
 
class Test1 {
    public static function printMe() {
        print 'This is nstest\test1\Test1::printSelf.'."\n";
    }
}
 
require "Test2.php";
test2\Test2::printMe(); 
复制代码
    运行结果等于上面正确的结果。最重要的差别就是该例使用了PHP名字空间中的相对定位。相信熟悉C++的开发者一定会想到use关键字,PHP也提供了该关键字,他们的功能是一致的,都是为了避免在后面的代码中,无需再通过全限定符(类名前加名字空间前缀)来引用其他名字空间中的类了。至于具体的语法规则,还是看看下面具体的代码和关键性注释吧。
 
复制代码
<?php
//Test2.php
namespace nstest\test2;
 
class Test2 {