这是在PHP中使用命名空间的好方法吗?

时间:2011-12-22 20:19:16

标签: php namespaces

我曾经研究过在PHP中使用命名空间,但最近看了一个使用use关键字的项目,然后访问了命名空间对象,好像它们没有命名空间一样正常。

我的问题是,下面的代码是否正确,它是一个文件index.php并使用名称空间MyLibrary\Base然后使用use来引入\MyLibrary\Registry {{1 }和\MyLibrary\User

然后它可以访问任何这些对象而不在它们前面放置命名空间,因此\MyLibrary\Request部分下面的实际代码看起来像普通的命名空间之前的php文件。

我在问你是否使用命名空间?或者我错过了什么?

文件:index.php

use

文件:registry.class.php

<?php
namespace MyLibrary\Base;

use \MyLibrary\Registry;
use \MyLibrary\User;
use \MyLibrary\Request;


class Base
{
    public $registry;

    function __construct($registry)
    {
        $this->registry = $registry;
        $this->user = New User;
        $this->request = new Request;
        # code...
    }
}
?>

2 个答案:

答案 0 :(得分:6)

是。 use - 语句将class-或namespace-name导入当前范围。要编写简短的原因,为什么PHP-devs实现名称空间;)

namespace MyFirstNamespace {
    class Foo {}
}
namespace MySecondNamespace {
    use \MyFirstNamespace\Foo as Bar;
    $foo = new Bar;
}

a)它使所有内容更具可读性,因为它比Vendor_Package_Foo_Bar_XyzClass和b)更短,你可以非常快速地交换类。

# use \MyFirstNamespace\Foo as Bar; // I don't like Foo anymore
use \MyFirstNamespace\SimilarToFoo as Bar;

答案 1 :(得分:3)

命名空间有很多优点。

第一个问题是如果它们存在于不同的命名空间中,则可以重用方法名称甚至类名称。示例:

namespace \myNamespace\data\postgres;

class DataBase extends \PDO
{
}

namespace \myNamespace\data\mysql;

class DataBase extends \PDO
{
}

您甚至可以重用通常为PHP函数保留的名称

namespace \myNamespace\dir;

function makedir ()
{
    if (// some condition is true)
    {
        \makedir ();
    }
}

所有这一切都旨在让您更轻松地使用来自不同来源的代码,而无需担心命名冲突。如果程序员有礼貌,可以遵守一些简单的规则,那么名称冲突的可能性就会大大降低。实际上,为了避免命名冲突,您需要关注的唯一规则就是使命名空间的第一级成为您自己的命名空间。例如,使用您的公司名称,或者将您标识为独特供应商的其他方式作为命名空间的第一级,一切都应该是好的。

例如,我在我编写的所有代码中使用\ gordian作为根命名空间,因为我可以在该命名空间下调用我喜欢的类,而不必担心它们会与选择不同根命名空间的人发生冲突。

那么您可能会问,PEAR惯例有什么问题?许多项目都遵循它们,包括流行的Zend框架。

答案是名字变得非常笨拙很快。例如,Zend遵循PEAR约定,使用一种伪命名空间。集合中的所有类都以Zend_开头,并且每个级别的层次都为名称添加了另一部分 泽 因此,您最终会使用Zend_Db_Adaptor_Abstract和Zend_Dojo_Form_Decorator_TabContainer等类名。

Zend应该更新他们的框架以使用命名空间(我告诉他们正在使用Zend Framework 2.0),然后将它们替换为\ Zend \ Db \ Adapter \ Abstract和\ Zend \ Dojo \ Form \ Decorator \ TabContainer代替。那么,你可能会问什么?答案是,您可以使用Use关键字将它们替换为更短的名称,如您所见。这意味着您不必继续编写完整的类名,而只需要写出您的别名。

use \Zend\Dojo\Forn\Decorator as Dec;

$a = new Dec\TabContainer; // Not easy to do without namespaces!

此外,如果您已经在给定的命名空间中,那么您甚至不必使用use关键字通过短名称访问同一命名空间中的其他项目,因为在这种情况下它会自动发生。对于框架编写者来说,这是一个巨大的节省时间。

例如,您可能会看到类似Zend Framework 2中的followign(因为我没有以任何方式处理它,这纯粹是一个示例,而不是来自实际的ZF2源)。

namespace \Zend\Db\Adaptor;

class Postgres extends Abstract // We don't need to use \Zend\Db\Adaptor\Abstract here because it's in the same namespace already anyway
{
}

还有其他好处,例如它使自动加载器变得非常简单(假设您的命名空间结构完全映射到您的文件系统目录结构)。

命名空间看起来像是那些并不是非常重要的功能之一,或者甚至看起来没有任何意义,但在使用它们一段时间之后它们的用处会突然变得非常明显。