助力软件开发企业降本增效 PHP / java源码系统,只需一次付费,代码终身使用! 广告
###laravel的解析流程分析 laravel 执行index.php文件的时候第一句执行的代码是: <pre> require __DIR__.'/../bootstrap/autoload.php'; </pre> 我们进入到bootstrap/autoload.php目录,将会看到执行的代码为: <pre> define('LARAVEL_START', microtime(true)); require __DIR__.'/../vendor/autoload.php'; $compiledPath = __DIR__.'/cache/compiled.php'; if (file_exists($compiledPath)) { require $compiledPath; } </pre> 重点看上面的第2行: <pre> require __DIR__.'/../vendor/autoload.php'; </pre> 可以得出,又执行了一次加载文件。我们深入这个文件进行分析。 包含执行了autoload_real.php,包含成功后还执行了getLoader()方法。 <pre> require_once __DIR__ . '/composer' . '/autoload_real.php'; return ComposerAutoloaderInit993490748ddc7f76227aaefe32fa99dc::getLoader(); </pre> ###autoload_real.php文件分析 <pre> class ComposerAutoloaderInit993490748ddc7f76227aaefe32fa99dc { private static $loader; public static function loadClassLoader($class) { if ('Composer\Autoload\ClassLoader' === $class) { require __DIR__ . '/ClassLoader.php'; } } public static function getLoader() { if (null !== self::$loader) { return self::$loader; } spl_autoload_register(array('ComposerAutoloaderInit993490748ddc7f76227aaefe32fa99dc', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInit993490748ddc7f76227aaefe32fa99dc', 'loadClassLoader')); </pre> 我们先来看getLoader()这个方法,这里面有一个典型的设计模式。单例设计模式,如果self::$loader不为空,直接返回self::$loader。如果为空的话,注册自己类下面的loadClassLoader方法,而这个方法会包含 当前目录下面的ClassLoader.php。 ###分析ClassLoader.php文件 这个类的主要功能是按照psr-0和psr-4 的标准加载文件。 1. set方法 将文件将namespace和路径$path信息全放入至变量: $this->prefixesPsr0 2. setPsr4 将namespace和路径$path信息放入至变量: $this->prefixDirsPsr4 3. 然后调用 classLoader里面的register 4. 而register这个方法会调用当前类下面的loadClass方法 <pre> public function loadClass($class) { if ($file = $this->findFile($class)) { includeFile($file); return true; } } </pre> 而这个方法又会执行自己类下面的findFile和findFileWithExtension这两个方法,将文件全部查找出来进行包含。 这样就实现了laravel按照psr-0和psr-4标准进行命名空间的自动加载。