什么是PHP名称空间?
大体上什么是名称空间?
一个外行的回答和一个例子将是伟大的。
什么是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.
命名空间允许您将一堆代码放在一个名称下,并且不会与类、函数和常量发生任何命名冲突。
它允许您的代码驻留在该名称空间中。
PHP使用有点争议的字符\来显示名称空间级别。人们很愤怒,因为它也被用作转义字。
要在PHP中使用名称空间,请在文件顶部使用如下内容。
namespace my\namespace;
您可以在关于名称空间的官方PHP文档中找到更多信息。
命名空间的工作方式类似于目录。您知道如何将文件放在与父目录(或任何其他目录)中的文件名称相同的目录中吗?好吧,命名空间让你在应用程序中为变量、函数和类做到这一点。
不久前,PHP中出现了一种趋势,即大量的静态函数类。调用这些函数的唯一方法是在调用前加上类名。这是对名称空间的一种原始尝试,但没有多少好处。
命名空间基本上允许您将代码放入容器中。这将防止使用相同名称的两个函数(以及类和变量)出现问题。
这在大型应用程序中非常有用,可以防止代码段共享相同名称的问题。
例如,假设我们需要两个名为“TheMessage”的函数。这两者都将分别打印(回显)不同的消息。 通常,这将导致语法错误,因为您不能有两个具有相同名称的函数。
要解决这个问题,可以将这些函数放到单独的名称空间中。这将允许您使用两个函数而不会出现任何错误。
命名空间对函数和类的作用就像作用域对变量的作用一样。它允许您在同一程序的不同部分使用相同的函数或类名,而不会引起名称冲突。
简单地说,可以将名称空间看作一个人的姓氏。如果有两个人叫“约翰”,你可以用他们的姓氏来区分他们。
的场景
假设您编写了一个使用名为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
该原理扩展到编程词中的命名空间。
Namespace就像将许多东西打包到一个包中。将命名空间想象成一个抽屉,您可以在其中放各种东西:一支铅笔、一把尺子、一张纸等等。为了避免使用彼此的物品,你们决定在抽屉上贴上标签,这样就能清楚地知道什么东西属于谁。
由于通过了解“命名空间”更容易了解关键字“使用”,所以让我首先通过一个基本的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”。
您可以使用命名空间来避免您创建的代码与内部PHP类/函数/常量或第三方类/函数/常量之间的名称冲突。 命名空间还能够别名(或缩短)Extra_Long_Names,旨在减少第一个问题,提高源代码的可读性。
我们都知道,名称空间和特征在PHP中并不新鲜,但仍然有许多PHP开发人员因为它们的复杂性而不使用这些伟大的概念。 所以,在这篇文章中。我会用例子来解释清楚。 什么是名称空间和特征?
如何在代码中实现它们以使代码可重用和可扩展?
名称空间的好处
您可以使用命名空间来避免您创建的代码与内部PHP类/函数/常量或第三方类/函数/常量之间的名称冲突。
命名空间还能够别名(或缩短)Extra_Long_Names,旨在减少第一个问题,提高源代码的可读性。 让我们通过一个例子来理解名称空间。 在htdocs(xampp)或WWW (xwamp)中创建名为“php_oops”的文件夹 在根目录下创建一个名为“namespaces”的新文件夹,然后在namespaces文件夹下创建一个文件index.php。
<?php
// FilePath:- namespaces/index.php
// let's say, we have two classes in index,
// here, these two classes have global space
class A
{
function __construct()
{
echo "I am at Global space, Class A";
}
}
class B
{
function __construct()
{
echo "I am at Global space, Class B";
}
}
// now create an object of class and
$object = new A; // unqualified class name
echo "<br/>";
$object = new \B; // fully qualified class name
// output:
I am at Global space, Class A
I am at Global space, Class B
参考, https://medium.com/@akgarg007/php-laravel-namespaces-and-traits-01-9540fe2969cb
我们经常需要给资源一个名字,一个标签,这将有助于我们理解和谈论它是什么。但是命名不仅仅是分配字符序列这么简单的任务。名称是用来区别事物的。
尽管一个标识符引用一个资源,但这并不意味着没有两个标识符是相同的。
我们可以通过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中,只有四种类型的代码会受到名称空间的影响:类、接口、函数和常量。
就是这样。