什么是名称空间?

什么是PHP名称空间?

大体上什么是名称空间?

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

110837 次浏览

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

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

什么是名称空间?在最广泛的定义中,名称空间是一种封装项的方式。在很多地方,这都是一个抽象的概念。例如,在任何操作系统中,目录用于对相关文件进行分组,并充当其中文件的名称空间。例如,foo.txt文件可以同时存在于/home/greg目录和/home/other目录中,但是foo.txt的两个副本不能同时存在于同一个目录中。此外,要访问/home/greg目录之外的foo.txt文件,必须在文件名前加上目录名,使用目录分隔符来获得/home/greg/foo.txt同样的原则也适用于编程领域的名称空间。

命名空间允许您将一堆代码放在一个名称下,并且不会与类、函数和常量发生任何命名冲突。

它允许你的代码在该命名空间中生活

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的控制器类,它位于路径中: < < em > app / Http /控制器/ em >从项目的根目录 还有另一个名为:Controller.php的控制器类,但这个类在路径中: 来自项目根目录的供应商/ laravel /框架/ src /照明/路由

如果你是php新手,你还不需要看源代码,因为它会让你困惑,相反,让我向你解释的部分 它是我们所关心的,并将帮助我们理解“名称空间”和“使用”。< / em > < / p > 所以事实上,我们的第一个控制器类 < em >应用程序/ Http /控制器/ Controller.php < / em >需要使用 第二个控制器类< em >供应商/ laravel /框架/ src /照明/路由/ Controller.php < / em >。 它实际上需要扩展这个类,以便能够访问它的内容来处理一些关键的路由功能

那么一个类如何扩展另一个具有相同名称的类呢? class Controller extends Controller吗?这是行不通的, 除非有办法实现区分这两个类,这时namespaceuse关键字就派上用场了 有助于完成的任务,允许使用;(类;方法;接口和常量),具有相同的名称,在相同的作用域 现在是如何在代码中完成的?很简单的!< / em >如果我们查看< em >应用程序/ Http /控制器/ Controller.php < / em >源代码,我们可以在类的顶部看到 namespace被声明为:namespace App\Http\Controllers,所以这就是你如何给你的类一个命名空间,这样它就可以被其他类引用 现在它看起来和从项目根目录到这个类的路径是一样的,差别很小,这就是使用" \ "而不是" / " (与windows命令提示符相同), 但还有一个区别,那就是名称空间中带有大写“A”的App和带有“App”的App 路径中小写的“a”。还要注意命名空间区分大小写 < / p > 所以命名空间是一个与路径不同的概念,它可以遵循路径结构,如果它有帮助,但它不必是到 类,方法,接口或常量为例,看看: 供应商/ laravel /框架/ src /照明/路由/ Controller.php源代码,

在类的顶部,我们看到命名空间被声明为:Illuminate\Routing

现在让我们来看看" use "关键字, 我们使用" use "关键字使我们的类意识到我们想在类

中使用的特定类或函数

所以我们没有引进或包括任何东西我们只是让我们的类知道我们将使用特定的类或 方法,通过它们的名称空间引用它们 让我们来看看< em >应用程序/ Http /控制器/ Controller.php < / em >的源代码, 正如你可以从这一行中看到的:" use Illuminate\Routing\Controller as BaseController ", " use "关键字后跟名称空间 对于目标类 (注意,Illuminate\Routing\Controller.php和Illuminate\Routing\Controller '不带。php扩展名'是可以互换的

我们可以使用" as "关键字和" use "关键字来给特定的类、方法、接口或常量一个别名 < em >应用程序/ Http /控制器/ Controller.php < / em >< em >照亮\路由\ Controller.php < / em >扩展为该行中的BaseController: “class Controller extends BaseController”。< / p >

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

命名空间是控制程序中名称的一个简单系统 它确保名称是唯一的,不会导致任何冲突

您可以使用命名空间来避免您创建的代码与内部PHP类/函数/常量或第三方类/函数/常量之间的名称冲突。 命名空间还具有别名(或缩短)Extra_Long_Names的能力,旨在减少第一个问题,提高源代码的可读性 我们都知道,名称空间和特征在PHP中并不新鲜,但仍然有许多PHP开发人员因为它们的复杂性而不使用这些伟大的概念。 所以,在这篇文章中。我会用例子来解释清楚。 什么是名称空间和特征?< / p >

如何在代码中实现它们以使代码可重用和可扩展?

名称空间的好处

您可以使用命名空间来避免您创建的代码与内部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
- - - - - - < p >引用 https://medium.com/@akgarg007/php-laravel-namespaces-and-traits-01-9540fe2969cb < / p >

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

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

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

例如时间!

假设在邮编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。和Author Namename

<?php


namespace Book;


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


?>

在另一个上下文中,我们用title表示Title of a Character。和Character's Name By name

<?php


namespace Character;


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


?>

当我们在两个上下文中都想要titlename时,我们必须明确区分Book TitleTitle of a Character。我们还必须明确区分Author NameCharacter's Name

<?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中,只有四种类型的代码受命名空间的影响:类、接口、函数和常量。

就是这样。