PSR-4 自动加载规范
最后更新于:2022-04-02 02:19:33
[TOC]
> [示例文档](https://learnku.com/docs/psr/psr-4-autoloader-example/1609)
## 示例
### 单一目录自动加载示例
详情
```
## 多目录加载的示例
详情
```
register();
*
* // 为命名空间前缀注册基本路径
* $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/src');
* $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/tests');
*
* 下述语句会让自动加载器尝试从
* /path/to/packages/foo-bar/src/Qux/Quux.php
* 中加载 \Foo\Bar\Qux\Quux 类
*
* prefixes[$prefix]) === false) {
$this->prefixes[$prefix] = array();
}
// 保留命名空间前缀的基本目录
if ($prepend) {
array_unshift($this->prefixes[$prefix], $base_dir);
} else {
array_push($this->prefixes[$prefix], $base_dir);
}
}
/**
* 加载给定类名的类文件
*
* @param string $class 合法类名
* @return mixed 成功时为已映射文件名,失败则为 false
*/
public function loadClass($class)
{
// 当前命名空间前缀
$prefix = $class;
// 通过完整的命名空间类名反向映射文件名
while (false !== $pos = strrpos($prefix, '\\')) {
// 在前缀中保留命名空间分隔符
$prefix = substr($class, 0, $pos + 1);
// 其余的是相关类名
$relative_class = substr($class, $pos + 1);
// 尝试为前缀和相关类加载映射文件
$mapped_file = $this->loadMappedFile($prefix, $relative_class);
if ($mapped_file) {
return $mapped_file;
}
// 删除 strrpos() 下一次迭代的尾部命名空间分隔符
$prefix = rtrim($prefix, '\\');
}
// 找不到映射文件
return false;
}
/**
* 为命名空间前缀和相关类加载映射文件。
*
* @param string $prefix 命名空间前缀
* @param string $relative_class 相关类
* @return mixed Boolean 无映射文件则为false,否则加载映射文件
*/
protected function loadMappedFile($prefix, $relative_class)
{
// 命名空间前缀是否存在任何基本目录
if (isset($this->prefixes[$prefix]) === false) {
return false;
}
// 通过基本目录查找命名空间前缀
foreach ($this->prefixes[$prefix] as $base_dir) {
// 用基本目录替换命名空间前缀
// 用目录分隔符替换命名空间分隔符
// 给相关的类名增加 .php 后缀
$file = $base_dir
. str_replace('\\', '/', $relative_class)
. '.php';
// 如果映射文件存在,则引入
if ($this->requireFile($file)) {
// 搞定了
return $file;
}
}
// 找不到
return false;
}
/**
* 如果文件存在从系统中引入进来
*
* @param string $file 引入文件
* @return bool 文件存在则 true 否则 false
*/
protected function requireFile($file)
{
if (file_exists($file)) {
require $file;
return true;
}
return false;
}
}
```
';