什么是PHP名称空间?

大体上什么是名称空间?

一个外行的回答和一个例子将是伟大的。


当前回答

我们经常需要给资源一个名字,一个标签,这将有助于我们理解和谈论它是什么。但是命名不仅仅是分配字符序列这么简单的任务。名称是用来区别事物的。

尽管一个标识符引用一个资源,但这并不意味着没有两个标识符是相同的。

我们可以通过GUID或添加关于名称空间的信息来防止或减少标识符冲突。Namespace是从中选择名称或标识符的域。当我们向标识符添加命名空间时,我们创建了限定名称。

例如时间!

假设在邮编99501中只有一个叫JOHN_SMITH的人。邮政编码86302的JOHN_SMITH也只有一个。那么,当我们提到JOHN_SMITH时,我们怎么知道我们说的是哪个JOHN_SMITH呢?

当我们在邮政编码99501的上下文中讨论,并提到JOHN_SMITH时,我们谈论的是邮政编码99501的JOHN_SMITH。

<?php

namespace zc99501;

const JOHN_SMITH = "John Smith from 99501";

?>

当我们在邮政编码86302的上下文中讨论,并提到JOHN_SMITH时,我们谈论的是邮政编码86302的JOHN_SMITH。

<?php

namespace zc86302;

const JOHN_SMITH = "John Smith from 86302";

?>

现在,如果一个邮编为99501的人和另一个邮编为86302的人想要谈论JOHN_SMITH,会发生什么?他们必须说来自99501的JOHN_SMITH做了这个,来自86302的JOHN_SMITH做了那个。

<?php

namespace zc99501;

const JOHN_SMITH = "John Smith from 99501";

namespace zc86302;

const JOHN_SMITH = "John Smith from 86302";

namespace Test;

echo \zc99501\JOHN_SMITH . PHP_EOL;
echo \zc86302\JOHN_SMITH . PHP_EOL;

?>

这里,\zc99501\JOHN_SMITH和\zc86302\JOHN_SMITH是限定名。

另一个例子。

假设在一个上下文中,当我们使用常量Title时,我们指的是Book Title。以及作者姓名。

<?php

namespace Book;

const title = "Don Quixote";
const name = "Miguel de Cervantes Saavedra";

?>

在另一种情况下,我们通过标题来表示角色的标题。以及角色的名字。

<?php

namespace Character;

const title = "Sir";
const name = "Sancho Panza";

?>

当我们在两个上下文中都需要标题和名字时,我们必须明确区分书名和角色的标题。我们还必须明确区分作者名和角色名。

<?php

namespace Book;

const title = "Don Quixote";
const name = "Miguel de Cervantes Saavedra";

namespace Character;

const title = "Sir";
const name = "Sancho Panza";

namespace Test;

echo \Book\title . PHP_EOL;
echo \Book\name . PHP_EOL;
echo \Character\title . PHP_EOL;
echo \Character\name . PHP_EOL;

?>

这里的\Book\title、\Book\name、\Character\title和\Character\name是限定名称。

注意:在PHP中,只有四种类型的代码会受到名称空间的影响:类、接口、函数和常量。

就是这样。

其他回答

Namespace就像将许多东西打包到一个包中。将命名空间想象成一个抽屉,您可以在其中放各种东西:一支铅笔、一把尺子、一张纸等等。为了避免使用彼此的物品,你们决定在抽屉上贴上标签,这样就能清楚地知道什么东西属于谁。

我们经常需要给资源一个名字,一个标签,这将有助于我们理解和谈论它是什么。但是命名不仅仅是分配字符序列这么简单的任务。名称是用来区别事物的。

尽管一个标识符引用一个资源,但这并不意味着没有两个标识符是相同的。

我们可以通过GUID或添加关于名称空间的信息来防止或减少标识符冲突。Namespace是从中选择名称或标识符的域。当我们向标识符添加命名空间时,我们创建了限定名称。

例如时间!

假设在邮编99501中只有一个叫JOHN_SMITH的人。邮政编码86302的JOHN_SMITH也只有一个。那么,当我们提到JOHN_SMITH时,我们怎么知道我们说的是哪个JOHN_SMITH呢?

当我们在邮政编码99501的上下文中讨论,并提到JOHN_SMITH时,我们谈论的是邮政编码99501的JOHN_SMITH。

<?php

namespace zc99501;

const JOHN_SMITH = "John Smith from 99501";

?>

当我们在邮政编码86302的上下文中讨论,并提到JOHN_SMITH时,我们谈论的是邮政编码86302的JOHN_SMITH。

<?php

namespace zc86302;

const JOHN_SMITH = "John Smith from 86302";

?>

现在,如果一个邮编为99501的人和另一个邮编为86302的人想要谈论JOHN_SMITH,会发生什么?他们必须说来自99501的JOHN_SMITH做了这个,来自86302的JOHN_SMITH做了那个。

<?php

namespace zc99501;

const JOHN_SMITH = "John Smith from 99501";

namespace zc86302;

const JOHN_SMITH = "John Smith from 86302";

namespace Test;

echo \zc99501\JOHN_SMITH . PHP_EOL;
echo \zc86302\JOHN_SMITH . PHP_EOL;

?>

这里,\zc99501\JOHN_SMITH和\zc86302\JOHN_SMITH是限定名。

另一个例子。

假设在一个上下文中,当我们使用常量Title时,我们指的是Book Title。以及作者姓名。

<?php

namespace Book;

const title = "Don Quixote";
const name = "Miguel de Cervantes Saavedra";

?>

在另一种情况下,我们通过标题来表示角色的标题。以及角色的名字。

<?php

namespace Character;

const title = "Sir";
const name = "Sancho Panza";

?>

当我们在两个上下文中都需要标题和名字时,我们必须明确区分书名和角色的标题。我们还必须明确区分作者名和角色名。

<?php

namespace Book;

const title = "Don Quixote";
const name = "Miguel de Cervantes Saavedra";

namespace Character;

const title = "Sir";
const name = "Sancho Panza";

namespace Test;

echo \Book\title . PHP_EOL;
echo \Book\name . PHP_EOL;
echo \Character\title . PHP_EOL;
echo \Character\name . PHP_EOL;

?>

这里的\Book\title、\Book\name、\Character\title和\Character\name是限定名称。

注意:在PHP中,只有四种类型的代码会受到名称空间的影响:类、接口、函数和常量。

就是这样。

在其他编程语言中有一些技术,比如名称空间(比如Java中的包)。它们被用来在一个项目中拥有多个具有相同名称的类。

来自php文档(http://www.php.net/manual/en/language.namespaces.rationale.php):

What are namespaces? In the broadest definition namespaces are a way of encapsulating items. This can be seen as an abstract concept in many places. For example, in any operating system directories serve to group related files, and act as a namespace for the files within them. As a concrete example, the file foo.txt can exist in both directory /home/greg and in /home/other, but two copies of foo.txt cannot co-exist in the same directory. In addition, to access the foo.txt file outside of the /home/greg directory, we must prepend the directory name to the file name using the directory separator to get /home/greg/foo.txt. This same principle extends to namespaces in the programming world.

命名空间用于封闭一组代码,以便它们可以在不同的地方使用而不会发生名称冲突。 把它看作jQuery无冲突方法,你会更好地理解它。

就像目录和文件一样,PHP中的命名空间用于对类、函数、接口和常量进行分组。

例子:

Filesystem      |   PHP Namespace
----------------|------------------
/Dir/File.txt   |  \Namespace\Class

它提供了一种包装来自全局空间的项的方法,并允许使用普通项名而不会在程序中引起名称冲突。 PHP 5.3.0和PHP 7支持它。

但是PHP命名空间与基于Unix的文件系统的类比存在一定的局限性:

                          | Filesystem            |        PHP Namespace
--------------------------|-----------------------|-------------------------
Cas sensitive             |       No              |        Yes                
--------------------------|-----------------------|-------------------------
Name with plain number    |       Yes             |        No
--------------------------|-----------------------|-------------------------
Path level                |       Yes             |        Yes   
--------------------------|-----------------------|-------------------------
Plain metacharacters name |       Yes             |        No        

该原理扩展到编程词中的命名空间。