一、全局安装

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

https://docs.phpcomposer.com/00-intro.html

二、代码

require_once './vendor/autoload.php';

一、autoload.php
   加载 composer/autoload_real.php 调用 autoload_real.php 下的 getLoader() 方法
  
二、autoload_real.php
getLoader() 方法
创建 composer\ClassLoader.php 的对象 $loader 1、静态调用 $useStaticLoader
加载 composer\autoload_static.php
回调 autoload_static.php 下的 getInitializer($loader) 方法 getInitializer() 方法
通过匿名函数绑定,为$loader 对象下的私有属性赋值
$prefixLengthsPsr4,
$prefixDirsPsr4,
$prefixDirsPsr4,
$classMap 注册自动加载 $loader->register(true); spl_autoload_register([$this, 'loadClass', true, $prepend]); function loadClass($class) {
if ($file = $this->findFile($class)) {
includeFile($file)
return true;
}
}      // ClassLoader.php 下的方法
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
} $file = $this->findFileWithExtension($class, '.php'); // Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
} if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
} if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
} return $file;
} function includeFile($file)
{
include $file;
}     private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$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;
}
}
}
}
} // PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
} // PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
} if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
} // PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
} // PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
} return false;
} 2、非静态调用
call_user_func(\Composer\Autoload\ComposerStaticInitd16dd22c4a12ecb92b3a245dff71e1fc::getInitializer($loader));

public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitd16dd22c4a12ecb92b3a245dff71e1fc::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitd16dd22c4a12ecb92b3a245dff71e1fc::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInitd16dd22c4a12ecb92b3a245dff71e1fc::$prefixesPsr0;
$loader->classMap = ComposerStaticInitd16dd22c4a12ecb92b3a245dff71e1fc::$classMap; }, null, ClassLoader::class);
} 解读:
call_user_func+Closure::bind()的模式,其实这里我们也可以完全按照常规的做法,引入一个配置文件的方式来实现,Closure::bind()返回一个Closure对象,即一个闭包函数,其中一共有三个参数: closure:需要绑定的匿名函数 newthis:需要绑定到匿名函数的对象,或者 NULL 创建未绑定的闭包 newscope:想要绑定给闭包的类作用域,或者 'static' 表示不改变。如果传入一个对象,则使用这个对象的类型名。 第一个参数好理解,第二个和第三个可以配合起来使用,当我们需要在闭包函数中使用$this的时候,我们需要给这个闭包绑定一个对象,如果闭包中使用了$this,那么newthis需要指定一个对应的对象;如果修改的属性是protected或者private,那么第三个参数不能忽略,指定为这个类。 例1: class A{
public $name;
protected $age;
}
$a = new A();
$new_a = Closure::bind(function(){
$this->name = 'nine';
} , null);
$new_a();
var_dump($new_a , $a);
此时会报错Using $this when not in object context in ...,说明这个上下文并没有指定$this。 例2: class A{
public $name;
protected $age;
}
$a = new A();
$new_a = Closure::bind(function(){
$this->name = 'nine';
$this->age = 10;
} , $a);
$new_a();
var_dump($new_a , $a);
此时会报错Cannot access protected property A::$age in...,属性是受保护的。 例3: class A{
public $name;
protected $age;
}
$a = new A();
$new_a = Closure::bind(function(){
$this->name = 'nine';
$this->age = 10;
} , $a , A::class);
$new_a();
var_dump($new_a , $a);
设置成功。
 

Composer 的autoload 实现的更多相关文章

  1. Composer的Autoload源码实现2——注册与运行

    前言 上一篇 文章我们讲到了 Composer 自动加载功能的启动与初始化,经过启动与初始化,自动加载核心类对象已经获得了顶级命名空间与相应目录的映射,换句话说,如果有命名空间 'App\Consol ...

  2. Composer的Autoload源码实现1——启动与初始化

    前言 上一篇文章,我们讨论了 PHP 的自动加载原理.PHP 的命名空间.PHP 的 PSR0 与 PSR4 标准,有了这些知识,其实我们就可以按照 PSR4 标准写出可以自动加载的程序了.然而我们为 ...

  3. composer的autoload来自动加载自己编写的函数库与类库?

    1.使用命令composer init生成composer.json文件,并编辑autoload选项内容如下: 其中又包含主要的两个选项: files 和 psr-4. files就是需要compos ...

  4. 如何让Composer的autoload支持自定义文件后缀名

    PHP的Composer工具规范了我们对系统各种资源库的加载格式,借助于PHP的自动加载机制,可以很大程度上简化在应用开发过程中的类库文件引用场景.但到目前为止,它有个不是问题的问题,就是文件后缀名只 ...

  5. composer设置autoload自己的代码

    "autoload": { "psr-4": {"": ["App/base", "App/src/contr ...

  6. composer的自动加载机制(autoload)

    composer的出现真是让人们眼前一亮,web开发从此变成了一件很『好玩』的事情,开发一个CMS就像在搭积木,从packagist中取出『积木』搭建在自己的代码中,一点一点搭建出一个属于自己的王国. ...

  7. Laravel Composer and ServiceProvider

    Composer and: 创建自定义类库时,按命名空间把文件夹结构组织好 composer.json>autoload>classmap>psr-4 composer dump-a ...

  8. Composer概述及其自动加载探秘

    composer概述 一开始,最吸引我的当属 Composer 了,因为之前从没用过 Composer . Composer 是PHP中用来管理依赖关系的工具,你只需在自己的项目中声明所依赖的外部工具 ...

  9. composer 自动加载原理

    核心当然是php5加入来的_autoload函数,当实例化一个不存在的类时,在报错之前,如果定义了_autoload函数,会进行调用此函数,此函数就可以执行相关的include操作. <?php ...

随机推荐

  1. Flutter基础用法解析

    解析开始 Flutter中一切皆widget,一切皆组件.学习Flutter中,必须首先了解Flutter的widget.先从最基本的MaterialApp和Scaffold开始了解 1 Materi ...

  2. P1552 [APIO2012]派遣

    链接 https://www.luogu.org/problemnew/show/P1552 思路 忍者数量肯定越多越好 那就从下到上的合并它的孩子 左偏树的话 顺便维护一个tot,大头堆,如果tot ...

  3. 【分布式事务】spring cloud集成lcn解决分布式事务

    参考地址:https://blog.csdn.net/u010882691/article/details/82256587 参考地址:https://blog.csdn.net/oyh1203/ar ...

  4. Why there is two completely different version of Reverse for List and IEnumerable?

    https://stackoverflow.com/questions/12390971/why-there-is-two-completely-different-version-of-revers ...

  5. Ubuntu关机时间过长,总是停在logo界面

    有时候我们总能遇到ubuntu关机的时候卡住,无法关机,一查看发现是" a stop job is running..." 然后后面接着一串等待时间. 这时候我们需要修改一下sys ...

  6. kubernetes 实战4_命令_Configure Pods and Containers

    Configure Service Accounts for Pods A service account provides an identity for processes that run in ...

  7. SAP月末结账年结流程

    SAP月末结账年结流程 SAP月末结账操作指南 流程描述:FI期末结帐流程包括应收帐款.应付帐款.固定资产.管理会计结帐.总帐结帐等一系列结帐过程,对于年结增加了余额结转及固定资产年度改变等动作,通过 ...

  8. HDU 3848 CC On The Tree(树形dp)

    http://acm.hdu.edu.cn/showproblem.php?pid=3848 题意: 求一棵树上两个叶子结点之间的最短距离. 思路: 两个叶子节点之间一定会经过非叶子节点,除非只有两个 ...

  9. python 部分函数

    abs(number) ,返回数字的绝对值cmath.sqrt(number) ,返回平方根,也可以应用于负数float(object) ,把字符串和数字转换为浮点数help() ,提供交互式帮助in ...

  10. mysql基本知识总结

    第一天 create database act_web character set utf8; : 创建数据库并设立编码(命令中是不允许使用“-”的) '; :创建用户并设立密码 grant all ...