2011-12-22 70 views
10

我已经研究了PHP中名称空间的使用,但是最近看到一个使用use关键字的项目,然后像没有名称空间那样访问名称空间对象。这是一个很好的使用PHP中的名称空间的方法

我的问题是,低于正确的代码,它HS文件index.php和使用命名空间MyLibrary\Base然后用它use在带来\MyLibrary\Registry\MyLibrary\User\MyLibrary\Request

然后,它可以访问这些对象没有把有名称空间,所以use部分下方的实际代码看起来像一个普通的名称空间php文件。

我在问,这是如何使用命名空间?或者我错过了什么?

文件:index.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... 
    } 
} 
?> 

文件:registry.class.php

<?php 
namespace MyLibrary\Registry; 

class Registry 
{ 
    public $user; 

    function __construct($user) 
    { 
     $this->user = $user; 
     # code... 
    } 
} 
?> 

回答

5

是。 use -statement将类或名称空间名称导入当前作用域。将所有内容写短的原因,为什么PHP的开发者实现的命名空间;)

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

一)它使一切更具可读性,因为它要短得多,比Vendor_Package_Foo_Bar_XyzClass和b)可以交换类使用非常快。

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

这真是太神奇了,现在我想要使用命名空间,因为我真的不想这样做,因为我想我必须在代码中处理看起来很邪恶的'\\'分隔符。这让我想起了Python,这是你必须导入库的方式。 – JasonDavis 2011-12-22 20:59:08

+0

其实我应该说,它就像C#在哪里他们使用...'使用系统;''使用System.Collections.Generic;'等等......我只是没有意识到他们正在导入命名空间。我还可以看到,使用点/周期作为NS分隔符会有多好。 – JasonDavis 2011-12-22 21:05:05

+0

一个简单的问题,就像你发布'use \ MyFirstNamespace \ Foo'吧';我知道你可以改变这个名字,但是在我看到的代码中,他们像我的例子那样做了......'use \ MyFirstNamespace \ Foo ;'然后通过使用'Foo'访问是可能的?注意我没有设置为其他任何东西,或者你会像这样设置它'use \ MyFirstNamespace \ Foo'作为Foo;'? – JasonDavis 2011-12-22 21:17:33

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_开头,并且每个级别的层次都添加了一个名称。
Ze 因此,最终得到类名Zend_Db_Adaptor_Abstract和Zend_Dojo_Form_Decorator_TabContainer。那么他们会被替换为\ Zend \ Db \ Adapter \ Abstract和\ Zend \ Dojo \ Form \ Decorator \以及Zend Framework 2.0版本。而不是TabContainer。那么,你可能会问什么?答案是,您可以使用Use关键字将它们别名为更短的名称,正如您已经看到的那样。这意味着你不必一直写完整的课程名称,而只需要写出你别名的内容。

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

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

更进一步,如果你在一个给定的命名空间是已经,那么你甚至不必使用关键字的使用由短名称相同的命名空间内访问其他项目,因为它自动发生你在这种情况下。对于框架编写者来说,这是一个巨大的节省时间。例如,您可能会在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 
{ 
} 

还有其他的好处太多,比如它使自动加载可笑的简单,使(前提是您的命名空间结构正好映射到你的文件系统的目录结构)。

命名空间看起来像是其中一个并不真正非常重要的功能,或者看起来似乎没有任何意义,但在使用它们一段时间后,它们的用处会突然变得非常明显。

相关问题