thinkphp5 惰性加载

来源:互联网 发布:手机怎么关联淘宝小号 编辑:程序博客网 时间:2024/05/16 04:29


从core/start.php 开始

base.php   中 最先加载 loader.php

// 载入Loader类
require CORE_PATH . 'Loader.php';

 

// 注册自动加载机制    public static function register($autoload = '')    {                // 注册系统自动加载        spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);        // 注册命名空间定义        self::addNamespace([            'think'    => LIB_PATH . 'think' . DS,            'behavior' => LIB_PATH . 'behavior' . DS,            'traits'   => LIB_PATH . 'traits' . DS,        ]);              // 加载类库映射文件        if (is_file(RUNTIME_PATH . 'classmap' . EXT)) {            self::addClassMap(__include_file(RUNTIME_PATH . 'classmap' . EXT));        }         // Composer自动加载支持        if (is_dir(VENDOR_PATH . 'composer')) {            self::registerComposerLoader();        }        // 自动加载extend目录        self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS);            }

register 中 定义命名空间,加载类库映射(路径为:RUNTIME_PATH),映射文件自定义,此函数中定义的参数,在后续的findFile 函数中 都有一 一对应。

当使用类,初始化时,如:

 
\think\Error::register();


经过之前的 \think\Loader::register()

 spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true);
进入
think\Loader::autoload

 // 自动加载    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)) {                return false;            }            __include_file($file);            return true;        }    }


    /**     * 查找文件     * @param $class     * @return bool     */    private static function findFile($class)    {               if (!empty(self::$map[$class])) {            // 类库映射            return self::$map[$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))) {                            var_dump($file);                            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, '\\')) {            // namespaced 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;            }        }        return self::$map[$class] = false;    }

 autoload 将根据类名,对自定义命名空间别名,已注册命名空间(library/think,library/traits,library/behavior 下的类文件,注意类的命名空间别写错),自定义classmap.php,extend目录 进行文件搜索,搜索存在 则  include 进来


classmap.php 中格式为:

return ['classname'=> class_file_dir ,......]

如:(类路径为 ..\core\library\dandexiong\test.php  )

return ["dandexiong\\test"=>LIB_PATH."dandexiong".DS."test".EXT];

使用如下:

namespace think;// ThinkPHP 引导文件// 加载基础文件 require __DIR__ . '/base.php'; var_dump(<span style="color:#FF0000;">\dandexiong\test::$t</span>); // 执行应用App::run()->send();



0 0
原创粉丝点击