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

时间:2022-09-10 23:10:08

I have studied the use of Namespaces in PHP a while back but recently looking at a project that used the use keyword and then accessed the namespaced object as if they were normal without namespace.

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

My question is, is the code below correct, it hs a file index.php and uses the namespace MyLibrary\Base it then uses use to bring in \MyLibrary\Registry \MyLibrary\User and \MyLibrary\Request

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

It then can access any of these object without putting there namespace in front of them, so the actual code below the use section looks like a normal pre-namespace php file.

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

I am asking if this is how you use namespaces? Or am I missing something?

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

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

File: registry.class.php

文件:registry.class.php

<?php
namespace MyLibrary\Registry;

class Registry
{
    public $user;

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

2 个解决方案

#1


5  

Yes. The use-statement imports the class- or namespace-name into the current scope. To write everything that short is the reason, why the PHP-devs implemented namespaces ;)

是。 use-statement将class-或namespace-name导入当前作用域。要编写所有简短的原因,为什么PHP-devs实现名称空间;)

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

a) it make everything more readable, because its much shorter, than Vendor_Package_Foo_Bar_XyzClass and b) you can exchange the classes to use very fast.

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

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

#2


3  

Namespacing has a lot of advantages to it.

命名空间有很多优点。

The first on is you can reuse method names and even class names if it makes sense provided they exist within a different namespace. Example:

第一个是你可以重用方法名称甚至类名,如果它们有意义,只要它们存在于不同的命名空间中。例:

namespace \myNamespace\data\postgres;

class DataBase extends \PDO
{
}

namespace \myNamespace\data\mysql;

class DataBase extends \PDO
{
}

You could even reuse names that are normally reserved for PHP functions

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

namespace \myNamespace\dir;

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

All of this is intended to make it easier to use code from different sources together without having to worry about naming conflicts. Provided programmers are courteous enough to observe a few simple rules then the chances of name conflicts are hugely reduced. Actually, pretty much the only rule you need to concern yourself with to avoid naming conflicts is to make the first level of your namespace your own. For example, use your company name, or some other way of identifying you as a unique vendor as the first level of your namespace and everything should be good.

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

For example I use \gordian as the root namespace in all the code I write, as I can then call my classes under that namespace anything I like without worrying about them colliding with someone who chose a different root namespace.

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

So what's wrong with PEAR conventions, you might ask? A lot of projects follow them, including the popular Zend framework.

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

The answer is names become very unwieldy very quickly. For instance, Zend, as it follows the PEAR convention, uses a sort of pseudo-namespacing. All the classes in the collection start with Zend_ and with each level of class hierachy add a further part to the name.
Ze As a result, you end up with class names like Zend_Db_Adaptor_Abstract and Zend_Dojo_Form_Decorator_TabContainer.

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

Should Zend update their framework to use namespaces (which I'm told is happening with Zend Framework 2.0) then they'd be replaced with \Zend\Db\Adaptor\Abstract and \Zend\Dojo\Form\Decorator\TabContainer instead. So what, you might ask? The answer is that you can alias them to much shorter names with the Use keyword, as you've already seen. This means you don't have to keep writing the full class name out, but only as far as to what you've aliased.

如果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!

Further more, if you're already in a given namespace, then you don't even have to use the use keyword to access other items within the same namespace by a short name, as it happens automatically for you in that case. For framework writers this is a huge timesaver.

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

For example, you might see something like the followign in Zend Framework 2 (as I'm not working on it in any way, this is purely an example and not from the actual ZF2 source).

例如,您可能会看到类似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
{
}

There are other benefits too, such as it makes autoloaders ridiculously simple to make (provided your namespace structure maps exactly onto your filesystem directory structure).

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

Namespaces can seem like one of those features that aren't really very important, or don't even seem to make any sense, but after using them for a little while their usefulness will suddenly become very obvious.

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

#1


5  

Yes. The use-statement imports the class- or namespace-name into the current scope. To write everything that short is the reason, why the PHP-devs implemented namespaces ;)

是。 use-statement将class-或namespace-name导入当前作用域。要编写所有简短的原因,为什么PHP-devs实现名称空间;)

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

a) it make everything more readable, because its much shorter, than Vendor_Package_Foo_Bar_XyzClass and b) you can exchange the classes to use very fast.

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

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

#2


3  

Namespacing has a lot of advantages to it.

命名空间有很多优点。

The first on is you can reuse method names and even class names if it makes sense provided they exist within a different namespace. Example:

第一个是你可以重用方法名称甚至类名,如果它们有意义,只要它们存在于不同的命名空间中。例:

namespace \myNamespace\data\postgres;

class DataBase extends \PDO
{
}

namespace \myNamespace\data\mysql;

class DataBase extends \PDO
{
}

You could even reuse names that are normally reserved for PHP functions

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

namespace \myNamespace\dir;

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

All of this is intended to make it easier to use code from different sources together without having to worry about naming conflicts. Provided programmers are courteous enough to observe a few simple rules then the chances of name conflicts are hugely reduced. Actually, pretty much the only rule you need to concern yourself with to avoid naming conflicts is to make the first level of your namespace your own. For example, use your company name, or some other way of identifying you as a unique vendor as the first level of your namespace and everything should be good.

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

For example I use \gordian as the root namespace in all the code I write, as I can then call my classes under that namespace anything I like without worrying about them colliding with someone who chose a different root namespace.

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

So what's wrong with PEAR conventions, you might ask? A lot of projects follow them, including the popular Zend framework.

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

The answer is names become very unwieldy very quickly. For instance, Zend, as it follows the PEAR convention, uses a sort of pseudo-namespacing. All the classes in the collection start with Zend_ and with each level of class hierachy add a further part to the name.
Ze As a result, you end up with class names like Zend_Db_Adaptor_Abstract and Zend_Dojo_Form_Decorator_TabContainer.

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

Should Zend update their framework to use namespaces (which I'm told is happening with Zend Framework 2.0) then they'd be replaced with \Zend\Db\Adaptor\Abstract and \Zend\Dojo\Form\Decorator\TabContainer instead. So what, you might ask? The answer is that you can alias them to much shorter names with the Use keyword, as you've already seen. This means you don't have to keep writing the full class name out, but only as far as to what you've aliased.

如果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!

Further more, if you're already in a given namespace, then you don't even have to use the use keyword to access other items within the same namespace by a short name, as it happens automatically for you in that case. For framework writers this is a huge timesaver.

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

For example, you might see something like the followign in Zend Framework 2 (as I'm not working on it in any way, this is purely an example and not from the actual ZF2 source).

例如,您可能会看到类似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
{
}

There are other benefits too, such as it makes autoloaders ridiculously simple to make (provided your namespace structure maps exactly onto your filesystem directory structure).

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

Namespaces can seem like one of those features that aren't really very important, or don't even seem to make any sense, but after using them for a little while their usefulness will suddenly become very obvious.

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