PHP命名空间的好处

时间:2012-02-24 08:35:37

标签: php namespaces

在对PHP中的命名空间进行一些研究之后,我试图找出除了将库项目组合在一起并重复使用相同类名之外的真正好处。

我不喜欢命名空间的是这些额外的行位于文件的顶部,你从'use core \ whatever \ class'调用类,这与标准方法没有关系。

另外 - 我无法找到有关的信息 - 在我们需要使用两个具有相同名称的类但在不同文件夹中包含相同方法名称的情况下会发生什么?我们仍然需要调用命名空间,但代码如何确定应该使用哪个类的方法?

我刚开始使用命名空间,请原谅我这个问题听起来很基本。

另外 - 它如何与静态方法一起工作 - 例如Helper类 - 我是否还必须指出我需要这个命名空间'use core \ whatever \ Helper'?

3 个答案:

答案 0 :(得分:12)

如果你有一个包含许多类的大项目,你最终会遇到命名冲突。您有db/mysql/adapter.phphttp/curl/adapter.php。要在没有名称空间的情况下处理此问题,您必须为您的类提供唯一的名称,例如Db_Mysql_AdapterHttp_Curl_Adapter,并且只要您引用这些类,就需要使用它们的全名。

命名空间允许您为您的班级Db\Mysql\AdapterHttp\Curl\Adapter命名,并且只需在其本地命名空间中AdapterMysql\AdapterCurl\Adapter分别引用它们在其他名称空间中。这可以节省很多的输入。

只需浏览Zend Framework version 1version 2的来源,即可看到差异。

  

在我们需要使用两个具有相同名称的类但在不同文件夹中包含相同方法名称的情况下会发生什么?我们仍然需要调用命名空间,但代码如何确定应该使用哪个类的方法?

如果您在名称空间Db\Mysql中,Adapter::foo()引用Db\Mysql\Adapter\Http\Curl\Adapter::foo()引用另一个namespace Db\Mysql; use Http\Curl\Adapter as HAdapter; Adapter::foo(); // Mysql adapter HAdapter::foo(); // Http adapter, same as: \Http\Curl\Adapter::foo(); 。如果您不想一直写出整个名称,也可以在文件顶部为该类添加别名:

{{1}}

答案 1 :(得分:1)

  

我不喜欢命名空间的是这些额外的行位于文件的顶部,你从'use core \ whatever \ class'调用类,这与标准方法没有关系。

命名空间逻辑上对类进行分组,避免污染全局范围。它还可以防止您制作大量的PHP代码 - 代码可能包含您网站中其他位置所需的部分代码。这使得更有理由将其放在另一个文件中,以供网站的另一部分使用。不要重复自己(干),在许多地方使用,但只编码一次!

  

在我们需要使用两个具有相同名称的类但在不同文件夹中包含相同方法名称的情况下会发生什么?我们仍然需要调用命名空间,但代码如何确定应该使用哪个类的方法?

命名空间使用aliases来防止出现这些问题。此外,有同名的课程?除非它们的名称相同但目的不同或子类别不同,例如api.document.eventsapi.ajax.events。否则,这是糟糕的程序设计。

答案 2 :(得分:0)

这个答案主要关注@deceze的答案。

他的论点是,有两个不同名称的类更复杂。是吗?

1。)他的示例代码不起作用,因为他从未包含文件。所以看起来应该是这样的:

namespace Db\Mysql;
use Http\Curl\Adapter as HAdapter;

include('Db/Mysql/Adapter.php');
include('Http/Curl/Adapter.php');   

Adapter::foo();  // Mysql adapter
HAdapter::foo(); // Http adapter, same as:
\Http\Curl\Adapter::foo();

2。)只要不将命名空间定义添加到此文件中,就不能包含adapter.php文件:

<?php
// this is Db/Mysql/Adapter.php

namespace Db/Mysql;

class Adapter {
  static function foo() {
  }
}

?>

现在是非命名空间变体:

include('db/mysql/adapter.php');
include('http/curl/adapter.php');

MysqlAdapter::foo(); // Mysql adapter
CurlAdapter::foo(); // Http adapter

adapter.php应如下所示:

<?php
// this is Db/Mysql/Adapter.php

class MysqlAdapter {
  static function foo() {
  }
}

?>

最后,您需要像以前一样编辑尽可能多的文件,像以前一样添加更多代码。所以这不是争论。

可能存在的唯一论据是避免出现冲突third party libraries的问题。但是你过去有多少名字冲突?您知道多少个库使用名称空间,因此您不需要编辑所有文件?

事实是,现实世界没有任何好处。这是从C世界采用的东西,在我看来增加了比收益更多的混乱。