###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標準進行命名空間的自動加載。