###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标准进行命名空间的自动加载。