在本教程中,我将介绍 php 中命名空间的基础知识。我将解释为什么您可能需要名称空间,并且我将向您展示如何在日常开发中使用 PHP 名称空间。
通常情况下,您最终会在 PHP 应用程序中使用来自不同供应商的第三方库。现在,如果一个库试图重用应用程序中另一个库已经使用的名称,则两个或多个库之间可能会发生冲突。您可能知道,如果您在代码中的某处声明了一个类、函数或const ant,那么您就不能在其他地方有另一个具有相同名称的类、函数或常量。如果存在名称冲突,它最终会破坏您的应用程序。
在 PHP 中引入命名空间之前,开发人员通过引入防止名称冲突的不同技术解决了这个问题。一种流行的解决方案是使用长类和函数名。例如,为了database在他们的库中引入这个类,他们会在它前面加上供应商名称,因此它会变成Vendorname_Database. 如果您在wordpress或 Zend框架中编写过代码,我相信您已经注意到了这种做法。
为了解决这个问题,从 PHP 5.3 开始,命名空间被引入 PHP。理解命名空间的最好方法是类比文件系统中的目录结构概念。用于对相关文件进行分组的目录用于命名空间。同一个目录下不能有两个同名文件,但不同目录下可以有同名文件。命名空间模仿 PHP 中的相同原理!
基本上,命名空间提供了一种将相关项目组合在一起的方法,避免了任何潜在的名称冲突。毫无疑问,这已成为 PHP 近期最重要的变化之一。事实上,大多数第三方库供应商和框架已经在他们的代码库中调整了命名空间。
这是对什么是命名空间的简要说明。我们将在接下来的几节中看到如何使用它们。
命名空间在 PHP 中的工作原理
在本节中,您将看到如何定义命名空间并在其下对相关项进行分组。
定义命名空间和子命名空间
首先要做的是使用namespacePHP 文件顶部的关键字定义名称空间。namespace关键字下的所有代码都成为命名空间代码。重要的是要注意这个关键字必须放在文件的顶部,确保它之前没有任何内容。唯一的例外是declare构造,您可以在定义命名空间之前使用它。
让我们快速看一下下面的代码片段,它演示了如何定义命名空间。
<?php namespace Tutsplus; // code which is defined here belongs to the Tutsplus namespace ?>
如您所见,上面的示例定义了Tutsplus命名空间。语句后定义的代码namespace Tutsplus;属于Tutsplus命名空间。您不能像我们在引入命名空间之前使用的那样直接访问此代码。我们将在下一节看到如何调用命名空间代码。
为了以更好的方式组织代码,PHP 允许您定义命名空间的层次结构,以便您可以在逻辑上划分和组织代码:这些称为子命名空间。
让我们修改前面的例子:
<?php namespace Tutsplus\Code; // code which is defined here belongs to the Tutsplus\Code namespace ?>
在上面的例子中,代码属于Tutsplus\Code子命名空间。事实上,您可以定义多个子命名空间来在整个库中划分代码,例如 Tutsplus\Code、 Tutsplus\Webdesign、 Tutsplus\Business等。
事实上,您会发现开发人员总是以模仿子名称空间并与子名称空间密切相关的方式设计目录结构。例如,在命名空间Baz下定义的类Foo\Bar应该在 Vendor\Foo\Bar目录下找到。在组织代码时,子命名空间非常有用!
如何使用命名空间
在上一节中,我们讨论了命名空间和子命名空间,以了解如何编写命名空间代码。在本节中,我们将看到如何调用命名空间代码。
考虑下面的例子,它定义了Tutsplus\Code命名空间。假设它在 mylib.php文件中。
<?php // mylib.php namespace Tutsplus\Code; // define a class class Tutorial { public function __construct() { echo "Fully qualified class name: ".__CLASS__."\n"; } } // define a function function fooBar() { echo "Fully qualified function name: ".__FUNCTION__."\n"; } // define a constant const RECORDS_PER_PAGE = 50; ?>
如您所见,这段代码在Tutsplus\Code命名空间中定义了一个类、一个函数和一个常量。
以下示例演示了如何使用mylib.php中定义的命名空间代码。
<?php // app.phprequire "mylib.php"; // instantiate the Tutorial class $objTutorial = new \Tutsplus\Code\Tutorial(); // call the function echo \Tutsplus\Code\fooBar(); // display the constant echo \Tutsplus\Code\RECORDS_PER_PAGE; ?>
首先,我们 使用语句包含了mylib.php文件。require
接下来,我们使用完全限定(命名空间)类名来实例化Tutorial该类。如果您使用new Tutorial() 而不是 new \Tutsplus\Code\Tutorial(),则会导致致命错误。
由于我们没有在app.php 文件中定义任何命名空间,因此代码属于全局命名空间。Tutorial因此,如果没有命名空间引用,您将无法访问该类。请注意,您可以 在 没有完全限定名称的情况下从命名空间内部Tutorial访问该类 。Tutsplus\Code
当然,当没有定义命名空间时,类、函数和常量将被放置在全局空间中,并以与支持命名空间之前相同的方式运行。
如何导入命名空间
正如您在上一节中看到的,您需要使用完全限定名称来引用命名空间中的项目。现在,在要引用命名空间项的任何地方都使用完全限定名称真的很麻烦。
幸运的是,您可以使用use运算符导入命名空间,从而避免指定完全限定名称的需要。
让我们快速修改app.php 文件来演示如何使用导入功能。
<?php // app.php use Tutsplus\Code; require "mylib.php"; // instantiate the Tutorial class $objTutorial = new Code\Tutorial(); // call the function echo Code\fooBar(); // display the constant echo Code\RECORDS_PER_PAGE; ?>
在上面的示例中,我们已经导入了Tutsplus\Code命名空间。现在,您只需Code在调用命名空间项时添加前缀,它就会自动转换为完全限定名称。
别名命名空间
别名类似于导入,但它允许您通过指定较短的名称来引用长名称空间。
理解它的最好方法是通过一个例子。
<?php // app.php use Tutsplus\Code as TC; use Tutsplus\Code\Tutorial as Tutorial; require "mylib.php"; // instantiate the Tutorial class with namespace alias TC $objTutorial = new TC\Tutorial(); // instantiate the Tutorial class with class alias Tut $objTutorial = new Tutorial(); // call the function echo TC\fooBar(); // display the constant echo TC\RECORDS_PER_PAGE; ?>
正如您在上面的示例中看到的,我们已经TC为命名空间创建了别名Tutsplus\Code,因此您可以使用它而不是指定完全限定名称。
事实上,在为类和接口创建别名时,别名非常有用。在上面的示例中,我们还为属于命名空间Tut的类创建了别名。所以你只需要使用 来实例化类,提高代码的可读性。TutorialTutsplus\Codenew Tutorial()Tutsplus\Code\Tutorial
在构建代码库以及它们带来的其他明显好处时,命名空间非常有用。对于 PHP 开发人员来说,命名空间是学习和使用的关键特性。
结论
在本文中,我们讨论了 PHP 中从 PHP 5.3 开始引入的最有用的新特性之一:命名空间。从基础开始,我们学习了各种主题,例如如何使用、导入和别名命名空间。
- 定义命名空间和子命名空间
- 如何使用命名空间