什么是PHP名称空间?
大体上什么是名称空间?
一个外行的回答和一个例子将是伟大的。
什么是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中,只有四种类型的代码会受到名称空间的影响:类、接口、函数和常量。
就是这样。
其他回答
由于通过了解“命名空间”更容易了解关键字“使用”,所以让我首先通过一个基本的Laravel项目来解释命名空间。
有一个名为:controller .php的控制器类,它位于以下路径: app/Http/Controllers从项目的根目录 还有另一个名为controller .php的控制器类,但是这个类在路径中: vendor/laravel/framework/src/Illuminate/Routing来自项目根目录
如果您是php新手,您还不需要查看源代码,因为它可能会使您感到困惑,相反,让我向您解释 它是我们所关心的,并将帮助我们理解“名称空间”和“使用”。
事实上,第一个控制器类 app/Http/Controllers/Controller.php需要使用 第二个控制器类vendor/laravel/framework/src/Illuminate/Routing/ controller .php。 它实际上需要扩展这个类,以便能够访问它的内容来处理一些关键的路由功能。
那么一个类如何扩展具有相同名称的另一个类呢? 类Controller扩展Controller?这是行不通的, 除非有办法区分这两个类,这时namespace和use关键字就派上用场了 有助于完成的任务,允许使用;(类;方法;接口和常量),具有相同的名称,在相同的作用域中。
now how is it done in the code? very simple! if we look at app/Http/Controllers/Controller.php source code, we can see at the top of the class namespace is declared as: namespace App\Http\Controllers, so this is how you give your class a namespace so it can be referenced by other classes now this looks the same as the path to this class from the project’s root directory, with little difference and that’s the usage of “\” instead of “/“ (same as command prompt in windows), but there is another difference and that’s the App with capital ‘A’ in the namespace versus ‘app’ with Lowercase ‘a’ in the path. Also note that namespace is case-sensitive.
所以名称空间和路径是不同的概念,它可以遵循路径结构,如果有帮助的话但它不需要是到 类,方法,接口或常量,例如看看: vendor/laravel/framework/src/Illuminate/Routing/Controller.php源代码
在类的顶部,我们看到命名空间被声明为:Illuminate\Routing
现在让我们来看看“使用”关键字, 我们使用" use "关键字使我们的类意识到我们想在类中使用的特定类或函数
so we are not importing or including anything we’re just letting our class know that we will be using a specific class or method by referencing them by their namespace let’s take a look at app/Http/Controllers/Controller.php source code, as you can see from the line: “use Illuminate\Routing\Controller as BaseController”, the “use” keyword followed by namespace for the target class (note that Illuminate\Routing\Controller.php and Illuminate\Routing\Controller ‘without .php extension’ are interchangeable)
我们可以使用“as”关键字和“use”关键字为特定的类、方法、接口或常量指定一个别名 app/Http/Controllers/Controller.php扩展Illuminate\Routing\Controller.php为BaseController: “类控制器扩展BaseController”。
在其他编程语言中有一些技术,比如名称空间(比如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.
命名空间对函数和类的作用就像作用域对变量的作用一样。它允许您在同一程序的不同部分使用相同的函数或类名,而不会引起名称冲突。
简单地说,可以将名称空间看作一个人的姓氏。如果有两个人叫“约翰”,你可以用他们的姓氏来区分他们。
的场景
假设您编写了一个使用名为output()的函数的应用程序。output()函数获取页面上的所有HTML代码并将其发送给用户。
稍后,应用程序变得更大,您希望添加新功能。您添加了一个允许生成RSS提要的库。这个库还使用一个名为output()的函数来输出最终提要。
当您调用output()时,PHP如何知道是使用您的output()函数还是RSS库的output()函数?它不是。除非您正在使用名称空间。
例子
我们如何解决有两个output()函数?简单。我们将每个output()函数置于其自己的名称空间中。
它看起来是这样的:
namespace MyProject;
function output() {
# Output HTML page
echo 'HTML!';
}
namespace RSSLibrary;
function output(){
# Output RSS feed
echo 'RSS!';
}
稍后,当我们想要使用不同的函数时,我们可以使用:
\MyProject\output();
\RSSLibrary\output();
或者我们可以声明我们在其中一个命名空间中,然后我们可以调用该命名空间的output():
namespace MyProject;
output(); # Output HTML page
\RSSLibrary\output();
没有命名空间?
如果没有命名空间,每次添加库时就必须(潜在地)修改大量代码,或者提出冗长的前缀以使函数名惟一。使用名称空间,我们可以避免在将第三方代码与自己的项目混合时产生命名冲突的麻烦。
就像目录和文件一样,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
该原理扩展到编程词中的命名空间。
命名空间用于封闭一组代码,以便它们可以在不同的地方使用而不会发生名称冲突。 把它看作jQuery无冲突方法,你会更好地理解它。