php的命名空间仅仅提供了一个逻辑上的类的隔离空间,我们在引用类时,仍要自己实现自动载入。思路就是使用一个未引入的类时,php自动触发spl_autoload_register这个方法,然后就会根据命名空间的结构解析为文件路径,引入相关的类文件啦。
下面仅仅编写一个简单的自动载入方法。
(1).优先使用classMap载入基类。
建立classes.php基类映射文件。当php自动加载时优先遍历该文件引入相关类文件。
<?php
return [
'foo\base\Application' => 'base/Application.php',
'foo\base\Compiler' => 'base/Compiler.php',
'foo\base\Container' => 'base/Container.php',
'foo\base\Controller' => 'base/Controller.php',
'foo\base\Event' => 'base/Event.php',
'foo\base\Model' => 'base/Model.php',
'foo\base\Object' => 'base/Object.php',
'foo\base\Router' => 'base/Router.php',
'foo\base\Template' => 'base/Template.php',
];
(2)载入其他类。其他类在app命名空间下,包括controllers,models两个子命名空间。
<?php
$classMap = require(__DIR__ . '/classes.php');
$dirList = ['controllers', 'models'];//强制仅有子两个命名空间
spl_autoload_register(function ($class) use ($classMap, $dirList){
if (!empty($classMap[$class])) {
require($classMap[$class]);
} else {
list($alias, $dir, $class) = explode('\\', $class);
if ($alias === 'app' && in_array($dir, $dirList)) {
$controllerFile = '../' . $dir . '/'. $class . '.php';
if (file_exists($controllerFile)) {
require($controllerFile);
} else {
throw new \Exception('控制器不存在!');
}
} else {
throw new \Exception('加载' . $class . '类文件失败!');
}
}
});
在某一类中使用using app\models\User;然后php就会自动载入models文件夹下的User类了。
要想使用第三方开发者的php类包,可以用composer自动载入。