在没有安装任何包的时候
vendor\composer\autoload_static.php里面的ComposerStaticInitd599f67bc4dd02223ec31783a7f7938f类只有
public static $classMap和public static function getInitializer(ClassLoader $loader)两个属性或者方法
执行 composer require phpoffice/phpspreadsheet
ComposerStaticInitd599f67bc4dd02223ec31783a7f7938f 会增加
public static $files
public static $prefixLengthsPsr4(这里保存的是包的跟目录(个人理解))
public static $prefixDirsPsr4(根据包的根目录去拿到执行php文件的根目录)
public static $prefixesPsr0
和修改了public static function getInitializer方法(有些语法还不太理解暂时没看,主要是讲一些数据赋值给ClassLoader $loader)
使用composer加载的包
新建一个php文件引入autoload.php
require_once DIR . ‘/vendor/autoload.php’;
调用这个类的功能
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
composer自动加载的执行流程
加载 /composer/autoload_real.php 文件
调用 ComposerStaticInitd599f67bc4dd02223ec31783a7f7938f::getLoader();
getLoader方法执行流程
这里只是单纯的对使用composer包的加载php文件进行理解,跳过其他加载过程
验证PHP版本(platform_check.php)
self::$loader = $loader = new \Composer\Autoload\ClassLoader(实现了PSR-0,PSR-4和classmap类加载器)
加载 vendor\composer\autoload_static.php文件(会验证PHP版本和zend_loader_file_encoded方法,zend_loader_file_encoded存在应该是使用其他逻辑)
调用\Composer\Autoload\ComposerStaticInitd599f67bc4dd05423ece1783a7f7938f::getInitializer($loader)方法
getInitializer方法主要是赋值ComposerStaticInitd599f67bc4dd02223ec31783a7f7938f类中的$prefixLengthsPsr4、$prefixDirsPsr4等给ClassLoader对象
注册自动加载器($loader->register(true);)
当创建phpoffice/phpspreadsheet包里面的对象的时候,找不到这个类会调用注册的自动加载器
loadClass($class) -> findFile($class) -> findFileWithExtension($class, ‘.php’)
loadClass 找到相关文件后,引入(include)这个文件
findFile 查找定义类的文件的路径并返回文件路径
findFileWithExtension 根据$prefixLengthsPsr4、$prefixDirsPsr4来找到这个类 返回文件路径
这就是new \PhpOffice\PhpSpreadsheet\Spreadsheet() 引入Spreadsheet.php文件的大致流程
composer包的关键代码和注释
index.php
require_once __DIR__ . '/vendor/autoload.php';
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
autoload.php
require_once __DIR__ . '/composer/autoload_real.php';return ComposerStaticInitd599f67bc4dd02223ec31783a7f7938f::getLoader();
composer/autoload_real.php部分代码
<?php
class ComposerStaticInitd599f67bc4dd02223ec31783a7f7938f{
private static $loader;
public static function getLoader(){
if (null !== self::$loader) {
return self::$loader;
}
require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInitd599f67bc4dd05423ece1783a7f7938f', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
spl_autoload_unregister(array('ComposerAutoloaderInitd599f67bc4dd05423ece1783a7f7938f', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require __DIR__ . '/autoload_static.php';
call_user_func(
\Composer\Autoload\ComposerStaticInitd599f67bc4dd05423ece1783a7f7938f::getInitializer($loader)
);
} else {
}
$loader->register(true);
return $loader; }}
new \PhpOffice\PhpSpreadsheet\Spreadsheet() 引入Spreadsheet.php文件的大致流程
ClassLoader.php
<?php
namespace Composer\Autoload;
class ClassLoader{
private $vendorDir;
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
public function loadClass($class){
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}}
public function findFile($class){
$file = $this->findFileWithExtension($class, '.php');
return $file;
}
private function findFileWithExtension($class, $ext){
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
return false;
}}
function includeFile($file){
include $file;
}