【ThinkPhp5源码学习】-注册自动加载(一)

发布于:2022-12-14 ⋅ 阅读:(405) ⋅ 点赞:(0)

测试用例

1.自动加载类spl_autoload_register

a.php

<?php

class a

{

    function aaa(){

        var_dump("aaa");
    }

}

b.php

<?php

class bbb

{

    function bbb(){

        var_dump("bbb");
    }

}

c.php

<?php

spl_autoload_register(function($class){

    require_once($class.".php");

});

$a = new a;

$a->aaa();

输出结果

<?php
spl_autoload_register('autoload',true,true);
function autoload($class){
	include './'.$class.'.php';
}
$a = new a;
$a->aaa();
<?php
class a{
	function aaa(){
		var_dump("aaa");
	}
}

2.在thinkphp5中应用

<?php
spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);

如果调用一个不存在的类时则调用autoload这个方法

$rootPath = self::getRootPath();

$rootPath = thinkphp代码位置;

self::$composerPath = $rootPath . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR;

self:$composerPath = 'thinkphp代码位置'./verdor/composer/;

if (is_dir(self::$composerPath)) {
    if (is_file(self::$composerPath . 'autoload_static.php')) {
        require self::$composerPath . 'autoload_static.php';
        $declaredClass = get_declared_classes();   
        $composerClass = array_pop($declaredClass); 
        foreach (['prefixLengthsPsr4', 'prefixDirsPsr4', 'fallbackDirsPsr4', 'prefixesPsr0', 'fallbackDirsPsr0', 'classMap', 'files'] as $attr) {
            if (property_exists($composerClass, $attr)) {
                self::${$attr} = $composerClass::${$attr};
            }
        }
    } else {
        self::registerComposerLoader(self::$composerPath);
    }
}

引入文件'thinkphp代码位置'./verdor/composer/autoload_static.php

获取autoload_static文件中ComposerStaticInit05f955dd7900fdf6b8c08829b0d31578类,

循环['prefixLengthsPsr4', 'prefixDirsPsr4', 'fallbackDirsPsr4', 'prefixesPsr0', 'fallbackDirsPsr0', 'classMap', 'files']

查看ComposerStaticInit05f955dd7900fdf6b8c08829b0d31578类中是否存在这些属性,

如果存在则self::这些属性=ComposerStaticInit05f955dd7900fdf6b8c08829b0d31578::这些属性

// 注册命名空间定义
self::addNamespace([
    'think'  => __DIR__,
    'traits' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'traits',
]);

addNamespace(['think'=>'thnkphp代码位置'/thinkphp/think,'traits'=>'thnkphp代码位置'/thinkphp/traits]); 

// 注册命名空间
public static function addNamespace($namespace, $path = '')
{
    if (is_array($namespace)) {
        foreach ($namespace as $prefix => $paths) {
            self::addPsr4($prefix . '\\', rtrim($paths, DIRECTORY_SEPARATOR), true);
        }
    } else {
        self::addPsr4($namespace . '\\', rtrim($path, DIRECTORY_SEPARATOR), true);
    }
}

addPsr4('think\\','thnkphp代码位置'/thinkphp/think) 

addPsr4('think\\','thnkphp代码位置'/thinkphp/traits) 

// 添加Psr4空间
    private static function addPsr4($prefix, $paths, $prepend = false)
    {
        if (!$prefix) {
            // Register directories for the root namespace.
            if ($prepend) {
                self::$fallbackDirsPsr4 = array_merge(
                    (array) $paths,
                    self::$fallbackDirsPsr4
                );
            } else {
                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;
        } elseif ($prepend) {
            // Prepend directories for an already registered namespace.
            self::$prefixDirsPsr4[$prefix] = array_merge(
                (array) $paths,
                self::$prefixDirsPsr4[$prefix]
            );
        } else {
            // Append directories for an already registered namespace.
            self::$prefixDirsPsr4[$prefix] = array_merge(
                self::$prefixDirsPsr4[$prefix],
                (array) $paths
            );
        }
    }

$preficLengthsPsr4['t']['think'] = '?';

$preficDirsPsr4['think'] = '?';

$preficLengthsPsr4['t']['traits'] = '?';

$preficDirsPsr4['traits'] = '?';

// 加载类库映射文件
if (is_file($rootPath . 'runtime' . DIRECTORY_SEPARATOR . 'classmap.php')) {
    self::addClassMap(__include_file($rootPath . 'runtime' . DIRECTORY_SEPARATOR . 'classmap.php'));
}

php think optimize:autoload,可生成classmap.php提高加载性能,这里暂时不运行

 self::addAutoLoadDir($rootPath . 'extend');
// 注册自动加载类库目录
public static function addAutoLoadDir($path)
{
    self::$fallbackDirsPsr4[] = $path;
}

$fallbackDirsPsr4[]='thinkphp代码位置'/extend;

本文含有隐藏内容,请 开通VIP 后查看