composer的源碼分析
這一篇文章,爲了弄清楚composer的自動加載原理,我們試着來分析composer的源碼。
代碼不算太多,信息量卻很大。通讀一遍之後,有幾個疑問:
1)autoload_real中getLoader(),使用spl_autoload_register註冊了loadClassLoader函數,當它成功new出該文件中核心類 ClassLoader() 後,爲什麼又銷燬了該函數?
2)autoload_real中以 $useStaticLoader 的值進行選擇進行不同方式的初始化,爲什麼一定分兩種,靜態初始化是有什麼優勢嗎?
3)爲什麼autoload_real和autoload_static中的類名後面需要加hash值,ClassLoader.php中的類名卻不需要hash值
4)Closure::bind的作用是什麼?
5)實現全局函數的自動加載,爲什麼不直接 require $includeFiles 裏面的每個文件名,而要用類外面的函數 composerRequire... ?
帶着這些疑問,我們再去細緻地分析composer源碼,看看能不能找到問題的答案。
一、啓動
Composer只是一個依賴管理工具,要想使用它提供的服務,還需要先將vendor/autoload.php引入纔行
1 <?php require __DIR__ . '/vendor/autoload.php';//自動加載
二、vendor文件夾
1. vendor/autoload.php
這纔是Composer真正開始的地方
1 <?php 2 3 // autoload.php @generated by Composer 4 5 require_once __DIR__ . '/composer/autoload_real.php'; 6 7 return ComposerAutoloaderInitdc5a5cb6ab1a9737fc8d7dc74cbe50ca::getLoader();
2. vendor/composer
打開composer文件夾,可以看到:
主要就是這7個核心文件在發揮作用。
其中,前面4個是普通的php文件,用於存放自動加載需要的相關內容,後面3個是php類文件,是貫穿整個自動加載實現的核心部分。
1)autoload_classmap.php
自動加載的最簡單形式,有完整的命名空間和文件目錄的映射。
2)autoload_files.php
用於加載全局函數的文件,存放各個全局函數所在的文件路徑名
3)autoload_namespaces.php
符合 PSR0 標準的自動加載文件,存放着頂級命名空間與文件的映射
4)autoload_psr4.php
符合 PSR4 標準的自動加載文件,存放着頂級命名空間與文件的映射
5)autoload_real.php
自動加載功能的引導類,這是composer真正開始的地方。類名爲 ComposerAutoloaderInit... 後面是隨機生成的hash值
6)autoload_static.php
頂級命名空間初始化類,用於給核心類初始化頂級命名空間。類名爲ComposerStaticInit... 後面是隨機生成的hash值
7)ClassLoader.php
composer 自動加載功能的核心類,類名爲ClassLoader。
三、Composer的自動加載原理
我們先要從autoload_real.php開始着手,因爲這纔是composer真正開始的地方,它的實現大概分爲下面的6個部分,我們先理出來,後面再逐一分析。
1)第一部分:單例模式
2)第二部分:構造ClassLoader核心類
3)第三部分:初始化核心類對象(關鍵部分)
4)註冊自動加載核心類對象(關鍵部分)
5)全局函數的自動加載,也分爲兩種方式:靜態初始化和普通初始化
6)運行