自动加载类库介绍
首先来看thinkphp5
class Loader{
//加载其他类函数,通过register函数
public static function autoload($class)
{
// 检测命名空间别名
if (!empty(self::$namespaceAlias)) {
$namespace = dirname($class);
if (isset(self::$namespaceAlias[$namespace])) {
$original = self::$namespaceAlias[$namespace] . '' . basename($class);
if (class_exists($original)) {
return class_alias($original, $class, false);
}
}
}
if ($file = self::findFile($class)) {
// 非 Win 环境不严格区分大小写
if (!IS_WIN || pathinfo($file, PATHINFO_FILENAME) == pathinfo(realpath($file), PATHINFO_FILENAME)) {
__include_file($file);
return true;
}
}
return false;
}
//查找类文件是否存在
private static function findFile($class)
{
// 类库映射
if (!empty(self::$classMap[$class])) {
return self::$classMap[$class];
}
// 查找 PSR-4
$logicalPathPsr4 = strtr($class, '', DS) . EXT;
$first = $class[0];
if (isset(self::$prefixLengthsPsr4[$first])) {
foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) {
if (0 === strpos($class, $prefix)) {
foreach (self::$prefixDirsPsr4[$prefix] as $dir) {
if (is_file($file = $dir . DS . substr($logicalPathPsr4, $length))) {
return $file;
}
}
}
}
}
// 查找 PSR-4 fallback dirs
foreach (self::$fallbackDirsPsr4 as $dir) {
if (is_file($file = $dir . DS . $logicalPathPsr4)) {
return $file;
}
}
// 查找 PSR-0
if (false !== $pos = strrpos($class, '')) {
// namespace class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DS);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DS) . EXT;
}
if (isset(self::$prefixesPsr0[$first])) {
foreach (self::$prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (is_file($file = $dir . DS . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// 查找 PSR-0 fallback dirs
foreach (self::$fallbackDirsPsr0 as $dir) {
if (is_file($file = $dir . DS . $logicalPathPsr0)) {
return $file;
}
}
// 找不到则设置映射为 false 并返回
return self::$classMap[$class] = false;
}
//注册加载类
public function register(){
// 注册系统自动加载
spl_autoload_register($autoload ?: 'thinkLoader::autoload', true, true);
}
//注册命名空间
public static function addNamespace($namespace, $path = '')
{
if (is_array($namespace)) {
foreach ($namespace as $prefix => $paths) {
self::addPsr4($prefix . '', rtrim($paths, DS), true);
}
} else {
self::addPsr4($namespace . '', rtrim($path, DS), true);
}
}
/**
* 添加 PSR-4 空间
* @access private
* @param array|string $prefix 空间前缀
* @param string $paths 路径
* @param bool $prepend 预先设置的优先级更高
* @return void
*/
private static function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
self::$fallbackDirsPsr4 = $prepend ?
array_merge((array) $paths, self::$fallbackDirsPsr4) :
array_merge(self::$fallbackDirsPsr4, (array) $paths);
} elseif (!isset(self::$prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('' !== $prefix[$length - 1]) {
throw new InvalidArgumentException(
"A non-empty PSR-4 prefix must end with a namespace separator."
);
}
self::$prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
self::$prefixDirsPsr4[$prefix] = (array) $paths;
} else {
self::$prefixDirsPsr4[$prefix] = $prepend ?
// Prepend directories for an already registered namespace.
array_merge((array) $paths, self::$prefixDirsPsr4[$prefix]) :
// Append directories for an already registered namespace.
array_merge(self::$prefixDirsPsr4[$prefix], (array) $paths);
}
}
/**
* 注册 classmap
* @access public
* @param string|array $class 类名
* @param string $map 映射
* @return void
*/
//加载类库映射文件
public static function addClassMap($class, $map = '')
{
if (is_array($class)) {
self::$classMap = array_merge(self::$classMap, $class);
} else {
self::$classMap[$class] = $map;
}
}
}
下面我们手动编写一个自动加载类
<?php
/**
* Created by PhpStorm.
* User: hj
* Date: 2019/1/19
* Time: 20:21
*/
namespace think;
class Loader{
private static $psr4Map;
public static function register($loadFunction=null){
self::$psr4Map = parse_ini_file('file.env');
spl_autoload_register($loadFunction ?: 'thinkLoader::autoload', true, true);
}
public static function autoload($class){
//当前命名空间前缀
$prefix = $class;
while ($file = self::findFile($prefix)){
include $file;
if( class_exists($class, false) ){
return true;
}
return true;
}
return false;
}
/*
*/
private static function findFile($class){
foreach (self::$psr4Map as $key=>$val){
$file_name = TPDIR.DS.$val.DS.$class.'.php';
if (is_file($file_name)){
return $file_name;
}else{
return false;
}
}
}
/*
* @param $namespace array 命名空间
* */
private static function addNamespace(array $namespace){
foreach ($namespace as $key=>$value){
self::$psr4Map[$key] = $value;
}
}
private static function loadMappedFile($prefix,$relative_class){
var_dump($prefix);
var_dump($relative_class);
}
}
入口文件代码
if (strpos(PHP_OS,'WIN')){
define('DS','/');
}else{
define('DS','');
}
define('TPDIR',__DIR__);
include 'thinkLoader.php';
thinkLoader::register();
$db = new Db();
运行文件,并没有报错。