在没有安装任何包的时候
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; |
| } |
| |