命名空间概述

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

什么是命名空间?从最广泛的定义来看,命名空间是一种封装项目的方式。这可以被视为许多地方的一个抽象概念。例如,在任何操作系统中,目录都用于分组相关文件,并充当其中文件的命名空间。作为一个具体的例子,文件 foo.txt 可以同时存在于目录 /home/greg/home/other 中,但 foo.txt 的两个副本不能共存于同一个目录中。此外,要访问 /home/greg 目录之外的 foo.txt 文件,我们必须使用目录分隔符将目录名称追加到文件名,以获得 /home/greg/foo.txt。同样的原则也适用于编程世界中的命名空间。

在 PHP 世界中,命名空间旨在解决库和应用程序作者在创建可重用代码元素(如类或函数)时遇到的两个问题

  1. 您创建的代码与内部 PHP 类/函数/常量或第三方类/函数/常量之间的名称冲突。
  2. 能够为旨在缓解第一个问题的 Extra_Long_Names 创建别名(或缩短),从而提高源代码的可读性。

PHP 命名空间提供了一种将相关类、接口、函数和常量分组的方法。以下是在 PHP 中使用命名空间语法的示例

示例 #1 命名空间语法示例

<?php
namespace my\name; // 参见“定义命名空间”部分

class MyClass {}
function
myfunction() {}
const
MYCONST = 1;

$a = new MyClass;
$c = new \my\name\MyClass; // 参见“全局空间”部分

$a = strlen('hi'); // 参见“使用命名空间:回退到全局
// 函数/常量”部分

$d = namespace\MYCONST; // 参见“命名空间运算符和 __NAMESPACE__
// 常量”部分
$d = __NAMESPACE__ . '\MYCONST';
echo
constant($d); // 参见“命名空间和动态语言特性”部分
?>

注意: 命名空间名称不区分大小写。

注意:

命名空间名称 PHP 以及以该名称开头的复合名称(如 PHP\Classes)保留用于内部语言使用,不应在用户空间代码中使用。

添加注释

用户贡献注释 4 个注释

SteveWa
13 年前
我认为这可能对像我这样的新手有所帮助...

名称冲突意味着
您创建了一个名为 db_connect 的函数,而您在文件(即包含文件)中使用的其他代码也具有相同名称的相同函数。

为了解决这个问题,您将函数重命名为 SteveWa_db_connect,这会使您的代码更长且更难阅读。

现在,您可以使用命名空间来将您的函数名称与任何其他人的函数名称区分开来,您无需创建 extra_long_named 函数来解决名称冲突问题。

因此,命名空间就像指向文件路径的指针,您可以在其中找到正在使用的函数的来源
Dmitry Snytkine
13 年前
只是一个说明:命名空间(即使是嵌套的或子命名空间)不能仅仅是数字,它必须以字母开头。
例如,假设您想使用命名空间来对您的包进行版本控制或对您的 API 进行版本控制

namespace Mynamespace\1; // 非法
改为使用以下代码
namespace Mynamespace\v1; // 正确
pierstoval at gmail dot com
9 年前
对于通过搜索命名空间来到这里的人来说,请知道一个联盟已经研究了 PHP 的最佳实践,以允许开发人员拥有共同的编码标准。

这些最佳实践被称为“PHP 标准推荐”,也称为 PSR。

您可以在以下链接中查看它们:http://www.php-fig.org/psr

实际上,有 5 个编码标准类别
PSR-0:自动加载标准,其目标是简化命名空间的使用,以便将命名空间转换为文件路径。
PSR-1:基本编码标准,基本上就是标准 :)
PSR-2:编码风格指南,在哪里放置大括号、如何编写类等等。
PSR-3:日志记录接口,如何编写标准日志记录器。
PSR-4:改进的自动加载,以解决更多命名空间到路径的映射。

我要重点介绍的是 PSR-0 和 PSR-4:它们使用命名空间将 FQCN(完全限定类名 = 全命名空间 + 类名)解析为文件路径。
基本示例,您有以下目录结构
./src/Pierstoval/Tools/MyTool.php

PSR-0 或 PSR-4 标准的命名空间规定您可以将此路径转换为 FQCN。
如果您需要了解它的含义,请阅读自动加载的原则,因为它是几乎强制性的 ;) 。

结构
{path}/autoloader.php
{path}/index.php
{path}/src/Pierstoval/Tools/MyTool.php

文件

<?php
// {path}/index.php
include 'autoloader.php';
$tool = new Pierstoval/Tools/MyTool();
?>

<?php
// {path}/src/Pierstoval/Tools/MyTool.php
namespace Pierstoval\Tools;
class
MyTool {}
?>

<?php
// {path}/autoloader.php
function loadClass($className) {
$fileName = '';
$namespace = '';

// 将包含路径设置为 "src" 目录
$includePath = dirname(__FILE__).DIRECTORY_SEPARATOR.'src';

if (
false !== ($lastNsPos = strripos($className, '\\'))) {
$namespace = substr($className, 0, $lastNsPos);
$className = substr($className, $lastNsPos + 1);
$fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
}
$fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
$fullFileName = $includePath . DIRECTORY_SEPARATOR . $fileName;

if (
file_exists($fullFileName)) {
require
$fullFileName;
} else {
echo
'Class "'.$className.'" does not exist.';
}
}
spl_autoload_register('loadClass'); // 注册自动加载器
?>

一个标准化的自动加载器会获取你想实例化的类(MyTool)并获取全限定类名(FQCN),将其转换为文件路径,并检查文件是否存在。如果存在,它将 <?php include(); ?> 它,如果你正确地写了你的类,这个类将在其正确的命名空间内可用。
然后,如果你有以下代码
<?php $tool = new Pierstoval/Tools/MyTool(); ?>
自动加载器将把 FQCN 转换为以下路径
{path}/src/Pierstoval/Tools/MyTool.php

这可能是 PHP 框架开发中最好的实践,比如 Symfony 或其他。
shewa12kpi at gmail dot com
3 年前
<?php
// 以下是命名空间的简单用例。看看我们如何使用命名空间来使用相同名称的类。这就是命名空间解决命名冲突的方式。

namespace Mobile;

class
User
{

public
$name = 'mobile user';
}

$user = new \Mobile\User;
echo
$user->name;

namespace
TV ;

class
User
{
public static
$name = 'tv user';
}

echo
\TV\User::$name;
To Top