购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.15 命名空间

在PHP5.3之前,我们经常将类命名为Product_info_price_list之类,以避免类还有函数的命名冲突和污染。

另外还一个目标,比如我们想在一个项目中使用两个框架,需要我们从这些框架中抽取一些有用的函数或类,因为这些框架有着这样那样的优势,经过挑选后的整合是个大坑,那就是很多类的命名是一样的,重名冲突会相当严重。

从PHP 5.3之后,它顺应潮流,推出了命名空间(name space)这样一个概念。如果你写过Java或.NET,那么就能明白,这个概念就是用来解决上面这些命名混乱等问题的。命名空间可以让我们不用起那么长的名字,可以继续使用较短的名字来命名,也可以省却一些学英语的小烦恼。

PHP命名空间均声明在文件顶部,适用于所有在该文件中声明的类、方法和常数。

我会重点介绍命名空间对类的影响,这些原则也适合于其他项目。我们举例来说,下面这段代码都包含在名为Shipping的命名空间里,如代码清单2-32所示:

代码清单2-32 shipping的命名空间代码


namespace shipping
class courier {
      public $name
       public $home_country
      public static function getCourier$courier_list{
            return $courier_list
      }
}

正常情况下,如果想实例化一个Courier对象,PHP会在全局命名空间中寻找这个类,由于它已经被定义在shipping命名空间里了,结果肯定是找不到的。

正确引用的方法是使用它的全名:shipping\Courier(注意是反斜杠)。

当在全局命名空间里将所有的类整齐放入小命名空间时,这个工作当然是非常棒的,但当要在另一个命名空间的代码中包含类时我们该怎么办?遇到这种情况,只需要使用一个引导命名空间的标识:反斜杠放在类名的前面,表示PHP将从命名空间中的顶部开始查找。

因此,在任意命名空间中使用命名空间中的类,可以这样做:


namespace Fred
$courier = new \shipping\Courier();
  

要引用Courier这个类,我们需要知道自己在哪一个命名空间中,比如:

·在shipping命名空间中,称为Courier。

·在全局命名空间中,称为shipping\Courier。

·在其他命名空间中,需要从顶部开始,这样来指代它:\shipping\Courier。

为了突出命名空间的价值,我们可以在一个名为Fred的命名空间下声明另一个Courier类,而且在代码中两个对象可以使用相同的类名而不报错,只需在顶层命名空间中声明这两个类即可。

当我们想使用两个或更多框架下的类库而不出毛病时,如Laravel或Zend,这些框架中都可能有一个类叫Log。可以在命名空间内部再创建命名空间,注意命名空间之间用分隔符就可以。

举个例子,一个网站可能同时具有博客和电子商务的功能,它有类似这样一个命名空间的类结构:


Shop
       Products
            products
productCategory
      shipping
            Courier
admin
      user
            User

由于Courier类位于第3层,用命名空间声明时将shop\shipping放进一个文件顶部即可。

加上适当的前缀,我们使用通过命名空间操作符替代多个下划线的方法,解决了长类名的问题。PHP还是允许我们像操作数据表一样把名字进行简写,以指代命名空间,包括在一个文件中使用多个命名空间。

代码清单2-33描述了我们刚才所描述的一系列类,如下:

代码清单2-33 使用命名空间


use shop\shipping     //使用哪个命名空间
use admin\user as u   //命名空间别名
//我们用哪个命名空间的Courier
$couriers = shipping\Courier::getCouriersByCountry'China');
//浏览用户账号并显示名字
$user = new u\User();
Echo $user->getDisplayName();
  

我们可以看到,因为声明了shipping命名空间,可以将嵌套命名空间中的最低一层作为缩写。第二行的命名空间使用,我们将user重命名成u,可以用u这个空间名来引用这个类。

以上这些对于我们逐步解决多数特定元素的同名问题大有裨益,你完全可以为这些名字另取一个更有特色的简称来加以区分。

事实上,命名空间被更多地应用于自动加载(Auto Load)功能上,它长得也非常像目录分隔符。相对于PHP而言,命名空间是一个新增加的内容,我们需要在类库和框架两层概念中深入理解它们。 EI6j6s1ur41o6w1ekXn7e5fF/Lu7e4fE+BI0gL8ZsVUNlIXTMQ/0q1iCIWD4mVky

点击中间区域
呼出菜单
上一章
目录
下一章
×