namespace 会自动加载,但是我测试的两个文件并没有自动加载:
#/DB/MySql.class.php
namespace DB;
class MySql
{
public function __construct()
{
var_dump(__FILE__);
}
}
#/index.php
namespace Home;
use DB\MySql;
$mysql = new MySql();
Fatal error: Class 'DB\MySql' not found in D:\localhost\demo\space\index.php on line 23
修改 index.php 改成如下,可以了,但是为什么不能自动加载?
phpnamespace Home; use DB\MySql; spl_autoload_register(function ($class) { if ($class) { $file = str_replace('\\', '/', $class); $file .= '.class.php'; if (file_exists($file)) { include $file; } } }); $mysql = new MySql();
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
命名空间跟文件加载并无直接关系,
只是有些语言,将命名空间结构和文件结构对应起来了。
以php为例,
一般的命名空间结构,跟php文件结构是存在映射关系的,通过命名空间名称,就能算出该类的实际存储位置,
然后实例化的时候,会触发用设置的spl自动加载函数将文件引入。
实际执行代码的时候是
new \DB\MySql();找不到这个文件的时候就会调用你的autoload函数 并file_exists("DB/MySql.class.php"),在当前目录下查找这个文件,在找不到的情况下然后就是你看到的 错误命名空间可以理解成一种虚拟路径,比如:
即使
a.class.php和b.class.php存在于同一个文件夹下,在使用他们的时候也需要加入用命名空间。比如现在有一个c.php, 它和a.class.php与b.class.php在同一文件夹下:其中,两个
include的目的是把两个文件中的内容引入,这样才可以正常使用文件中的内容 (类、变量、函数等) 。而命名空间的作用在于:即使引入了类所在的文件,由于它们被加上了一层「虚拟路径」,因而在实例化的时候也需要加入各自的命名空间才行。而自动载入,目的是在于将「虚拟路径」和「真实文件路径」相对应,使得在实例化
new A\B\C()就相当于在使用./A/B/C.php文件中的类。有了这样一个约定,我们就可以在使用类时,只关注命名空间,而不用再繁琐地引入文件了。这是因为有这么一段代码(就是你写的spl_autoload_register那段),按照某一约定(PSR0/PSR4,即命名空间路径与实际文件路径相匹配) 帮我们把文件引入的工作给做了。至于为什么非得写这么一段
spl_autoload_register,那是因为这种对应约定还没被写入 PHP 的语言机制里。不然我们就可以像 Java 中定义和使用「包」的方式一样对待 PHP 项目代码了。