PHP Conference Japan 2024

命名空间概述

(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 条注释

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

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

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

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

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

namespace Mynamespace\1; // 非法
改为使用以下方式
namespace Mynamespace\v1; // 正确
178
pierstoval at gmail dot com
10 年前
对于通过搜索命名空间来到这里的人,请了解一个联盟已经研究了 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 = '';

// 将 include 路径设置为 "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
'类 "'.$className.'" 不存在。';
}
}
spl_autoload_register('loadClass'); // 注册自动加载器
?>

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

这可能是 PHP 框架开发(如 Symfony 等)中最好的实践。
26
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