composer实现自动加载代码备忘录(一)
2018-05-24 本文已影响14人
提莫小小队长
autoload_real.php源码中第一部分:
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13
{
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('ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13', 'loadClassLoader'));
.
.
.
这个文件定义了一个ComposerAutoloaderInit+Hash值命名的类,先看上面这段代码中的几个点。
- 定义了私有静态属性$loader
- 定义了静态方法loadClassLoader()
- 定义了静态方法getLoader()
这三点的作用:
- 静态属性$loader是因为后面在静态方法中的getLoader()中有一段
<?php
.
.
.
if (null !== self::$loader) {
return self::$loader;
}
这个是最简单的单例模式,因此$loader就是为了接收对象
- 静态方法loadClassLoader()的作用是为了require ClassLoader.php这个文件
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
这个类的参数$class为什么与'Composer\Autoload\ClassLoader'相等,是因为第三点
- 静态方法getLoader()中的代码
spl_autoload_register(array('ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13', 'loadClassLoader'));
首先通过spl_autoload_register()这个函数通过回调函数的机制在自动加载堆栈中注册了一个方法,这个方法就是
ComposerAutoloaderInit0d73cb3edef790764ea1c1c8b396cb13::loadClassLoader();
注册好了自动加载之后,紧接着
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
上面那段代码先执行new \Composer\Autoload\ClassLoader();因为这个类并不存在(因为我们之前并没有require过),所以就调用了堆栈中的loadClassLoader()方法,因此就执行了
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
这个$class参数就是上面new的类名,也就是Composer\Autoload\ClassLoader因此走进了if判断,进而
require __DIR__ . '/ClassLoader.php';
导入进了ClassLoader.php,这一部分就梳理完了
注:
- 回调函数可以用数组形式实现调用,
array('A','test');
当使用回调函数的时候,用数组形式传递,那么A就指的是类名,test是A类中的静态方法,方法必须是静态的
array($obj,'test');
$obj是实例化的对象,test是该对象的方法
附文档和参考文献: