composer 简单基础介绍
# 在当前目录初始化一个composer.json,按照提示一步步填写即可,会在当前目录生成文件
composer init
# 根据当前composer.json 生成依赖关系,默认安装到vendor
composer install
# 在当前项目引入特定的依赖包(xxx/xxx)
composer require xxx/xxx
# 从dist安装,用特定的包(xxx/xxx)创建项目
composer create-project --prefer-dist xxx/xxx 你的项目目录 2.2.*
# 更新某个依赖包,并更新composer.lock
composer update xxx/xxx
# 该操作会升级你项目所有可能的依赖包,并更新composer.lock **小心操作**
composer update
# 更新composer版本
composer self-update
#优化一下自动加载
composer dump-autoload --optimize
composer 版本介绍
[国内中文翻译版本](http://docs.phpcomposer.com/01-basic-usage.html#Package-Versions)
[查看官方的版本控制介绍](https://getcomposer.org/doc/articles/versions.md)
composer 加速
# 全局配置文件(推荐方式)
composer config -g repo.packagist composer https://packagist.phpcomposer.com
# 当前项目
composer config repo.packagist composer https://packagist.phpcomposer.com
# 上述命令将会在当前项目中的 composer.json 文件的末尾自动添加镜像的配置信息(你也可以自己手工添加):
"repositories": {
"packagist": {
"type": "composer",
"url": "https://packagist.phpcomposer.com"
}
}
composer 自动加载流程
composer 目录结构
composer 加载流程
1. 项目引入composer加载文件autoload.php
require __DIR__.'/../vendor/autoload.php';
2. composer引入自身的autoload_real.php;
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit0726b6b85af134cab7b1acd212d59852::getLoader();
3. 获取加载
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
//注册loadClassLoader函数到SPL __autoload函数队列中
spl_autoload_register(array('ComposerAutoloaderInit0726b6b85af134cab7b1acd212d59852', 'loadClassLoader'), true, true);
//自动加载并实例化$loader
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
//注销loadClassLoader
spl_autoload_unregister(array('ComposerAutoloaderInit0726b6b85af134cab7b1acd212d59852', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
//使用已经静态编译的所有加载配置
require_once __DIR__ . '/autoload_static.php';
//通过getInitializer方法把autoload_static的参数赋值给$loader加载器实例
call_user_func(\Composer\Autoload\ComposerStaticInit0726b6b85af134cab7b1acd212d59852::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
//注册自动加载函数到SPL __autoload函数队列中,注册到了$loader->loadClass方法
$loader->register(true);
//以下是始终记载files参数设置的所有文件,所以files配置的不是按需加载是都直接加载引入
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit0726b6b85af134cab7b1acd212d59852::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire0726b6b85af134cab7b1acd212d59852($fileIdentifier, $file);
}
return $loader;
}
composer 自动加载识别判断代码
public function loadClass($class)
{
//根据类名查找文件所在位置
if ($file = $this->findFile($class)) {
//引入文件
includeFile($file);
return true;
}
}
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;
}
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
//取得命名空间的首字母
$first = $class[0];
//如果存在于首字母的配置,直接循环判断找到文件并返回
if (isset($this->prefixLengthsPsr4[$first])) {
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
if (0 === strpos($class, $prefix)) {
foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
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;
}
加载引入流程到此,你的项目主要是通过composer注册过的加载配置类,都会直接可以操作,无法再手动引入
部分结构源码
autoload_classmap.php - [composer.json->autoload.classmap]
# 这个 map 是经过扫描指定目录(同样支持直接精确到文件)中所有的 .php 和 .inc 文件里内置的类而得到的
example: "classmap": ["src/", "lib/", "Something.php"]
$baseDir . '/app/Console/Kernel.php',
'App\\Exceptions\\Handler' => $baseDir . '/app/Exceptions/Handler.php',
'App\\Http\\Controllers\\ArticlesController' => $baseDir . '/app/Http/Controllers/ArticlesController.php',
'Illuminate\\Auth\\Access\\AuthorizationException' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/Access/AuthorizationException.php',
'Illuminate\\Auth\\Access\\Gate' => $vendorDir . '/laravel/framework/src/Illuminate/Auth/Access/Gate.php',
...
);
autoload_files.php - [composer.json->autoload.files] 该配置下的文件每次都会直接加载
example: "files": ["src/MyLibrary/functions.php"]
$vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'1d1b89d124cc9cb8219922c9d5569199' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest.php',
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
'e7223560d890eab89cda23685e711e2c' => $vendorDir . '/psy/psysh/src/Psy/functions.php',
'f0906e6318348a765ffb6eb24e0d0938' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
'58571171fd5812e6e447dce228f52f4d' => $vendorDir . '/laravel/framework/src/Illuminate/Support/helpers.php',
);
autoload_psr4.php - [composer.json->autoload.psr-4]
# demo1:
"psr-4": {
"Monolog\\": "src/",
"Vendor\\Namespace\\": ""
}
# demo2: 多目录对应一个命名空间搜索
"psr-4": { "Monolog\\": ["src/", "lib/"] }
# demo3: 任何命名空间的都会搜索
"psr-4": { "": "src/" }
array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/type-resolver/src', $vendorDir . '/phpdocumentor/reflection-docblock/src'),
'XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'),
'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'),
'TijsVerkoyen\\CssToInlineStyles\\' => array($vendorDir . '/tijsverkoyen/css-to-inline-styles/src'),
'Tests\\' => array($baseDir . '/tests'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'),
'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
'Symfony\\Component\\Routing\\' => array($vendorDir . '/symfony/routing'),
'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'),
'Symfony\\Component\\HttpKernel\\' => array($vendorDir . '/symfony/http-kernel'),
'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'),
'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
'Symfony\\Component\\CssSelector\\' => array($vendorDir . '/symfony/css-selector'),
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
'Ramsey\\Uuid\\' => array($vendorDir . '/ramsey/uuid/src'),
'Psy\\' => array($vendorDir . '/psy/psysh/src/Psy'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'),
'Laravel\\Tinker\\' => array($vendorDir . '/laravel/tinker/src'),
'Illuminate\\' => array($vendorDir . '/laravel/framework/src/Illuminate'),
'Faker\\' => array($vendorDir . '/fzaninotto/faker/src/Faker'),
'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'),
'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'),
'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache'),
'Doctrine\\Common\\Annotations\\' => array($vendorDir . '/doctrine/annotations/lib/Doctrine/Common/Annotations'),
'Doctrine\\Common\\' => array($vendorDir . '/doctrine/common/lib/Doctrine/Common'),
'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'),
'Cron\\' => array($vendorDir . '/mtdowling/cron-expression/src/Cron'),
'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'),
'App\\' => array($baseDir . '/app'),
);
autoload_namespaces.php
array($vendorDir . '/phpspec/prophecy/src'),
'Parsedown' => array($vendorDir . '/erusev/parsedown'),
'Mockery' => array($vendorDir . '/mockery/mockery/library'),
'JakubOnderka\\PhpConsoleHighlighter' => array($vendorDir . '/jakub-onderka/php-console-highlighter/src'),
'JakubOnderka\\PhpConsoleColor' => array($vendorDir . '/jakub-onderka/php-console-color/src'),
'Doctrine\\DBAL\\' => array($vendorDir . '/doctrine/dbal/lib'),
'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib'),
'Doctrine\\Common\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib'),
'Doctrine\\Common\\Collections\\' => array($vendorDir . '/doctrine/collections/lib'),
);
autoload_static.php
__DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
'1d1b89d124cc9cb8219922c9d5569199' => __DIR__ . '/..' . '/hamcrest/hamcrest-php/hamcrest/Hamcrest.php',
'2c102faa651ef8ea5874edb585946bce' => __DIR__ . '/..' . '/swiftmailer/swiftmailer/lib/swift_required.php',
'5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
'e7223560d890eab89cda23685e711e2c' => __DIR__ . '/..' . '/psy/psysh/src/Psy/functions.php',
'f0906e6318348a765ffb6eb24e0d0938' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
'58571171fd5812e6e447dce228f52f4d' => __DIR__ . '/..' . '/laravel/framework/src/Illuminate/Support/helpers.php',
);
public static $prefixLengthsPsr4 = array (
'p' =>
array (
'phpDocumentor\\Reflection\\' => 25,
),
'X' =>
array (
'XdgBaseDir\\' => 11,
),
'W' =>
array (
'Webmozart\\Assert\\' => 17,
),
'T' =>
array (
'TijsVerkoyen\\CssToInlineStyles\\' => 31,
'Tests\\' => 6,
),
'S' =>
array (
'Symfony\\Polyfill\\Mbstring\\' => 26,
'Symfony\\Component\\Yaml\\' => 23,
'Symfony\\Component\\VarDumper\\' => 28,
'Symfony\\Component\\Translation\\' => 30,
'Symfony\\Component\\Routing\\' => 26,
'Symfony\\Component\\Process\\' => 26,
'Symfony\\Component\\HttpKernel\\' => 29,
'Symfony\\Component\\HttpFoundation\\' => 33,
'Symfony\\Component\\Finder\\' => 25,
'Symfony\\Component\\EventDispatcher\\' => 34,
'Symfony\\Component\\Debug\\' => 24,
'Symfony\\Component\\CssSelector\\' => 30,
'Symfony\\Component\\Console\\' => 26,
),
'R' =>
array (
'Ramsey\\Uuid\\' => 12,
),
'P' =>
array (
'Psy\\' => 4,
'Psr\\Log\\' => 8,
'PhpParser\\' => 10,
),
'M' =>
array (
'Monolog\\' => 8,
),
'L' =>
array (
'League\\Flysystem\\' => 17,
'Laravel\\Tinker\\' => 15,
),
'I' =>
array (
'Illuminate\\' => 11,
),
'F' =>
array (
'Faker\\' => 6,
),
'D' =>
array (
'Dotenv\\' => 7,
'Doctrine\\Instantiator\\' => 22,
'Doctrine\\Common\\Cache\\' => 22,
'Doctrine\\Common\\Annotations\\' => 28,
'Doctrine\\Common\\' => 16,
'DeepCopy\\' => 9,
),
'C' =>
array (
'Cron\\' => 5,
'Carbon\\' => 7,
),
'A' =>
array (
'App\\' => 4,
),
);
public static $prefixDirsPsr4 = array (
'phpDocumentor\\Reflection\\' =>
array (
0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src',
1 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src',
2 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src',
),
'XdgBaseDir\\' =>
array (
0 => __DIR__ . '/..' . '/dnoegel/php-xdg-base-dir/src',
),
'Webmozart\\Assert\\' =>
array (
0 => __DIR__ . '/..' . '/webmozart/assert/src',
),
'TijsVerkoyen\\CssToInlineStyles\\' =>
array (
0 => __DIR__ . '/..' . '/tijsverkoyen/css-to-inline-styles/src',
),
'Tests\\' =>
array (
0 => __DIR__ . '/../..' . '/tests',
),
'Symfony\\Polyfill\\Mbstring\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
),
'Symfony\\Component\\Yaml\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/yaml',
),
'Symfony\\Component\\VarDumper\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/var-dumper',
),
'Symfony\\Component\\Translation\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/translation',
),
'Symfony\\Component\\Routing\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/routing',
),
'Symfony\\Component\\Process\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/process',
),
'Symfony\\Component\\HttpKernel\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/http-kernel',
),
'Symfony\\Component\\HttpFoundation\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/http-foundation',
),
'Symfony\\Component\\Finder\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/finder',
),
'Symfony\\Component\\EventDispatcher\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/event-dispatcher',
),
'Symfony\\Component\\Debug\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/debug',
),
'Symfony\\Component\\CssSelector\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/css-selector',
),
'Symfony\\Component\\Console\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/console',
),
'Ramsey\\Uuid\\' =>
array (
0 => __DIR__ . '/..' . '/ramsey/uuid/src',
),
'Psy\\' =>
array (
0 => __DIR__ . '/..' . '/psy/psysh/src/Psy',
),
'Psr\\Log\\' =>
array (
0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
),
'PhpParser\\' =>
array (
0 => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser',
),
'Monolog\\' =>
array (
0 => __DIR__ . '/..' . '/monolog/monolog/src/Monolog',
),
'League\\Flysystem\\' =>
array (
0 => __DIR__ . '/..' . '/league/flysystem/src',
),
'Laravel\\Tinker\\' =>
array (
0 => __DIR__ . '/..' . '/laravel/tinker/src',
),
'Illuminate\\' =>
array (
0 => __DIR__ . '/..' . '/laravel/framework/src/Illuminate',
),
'Faker\\' =>
array (
0 => __DIR__ . '/..' . '/fzaninotto/faker/src/Faker',
),
'Dotenv\\' =>
array (
0 => __DIR__ . '/..' . '/vlucas/phpdotenv/src',
),
'Doctrine\\Instantiator\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/instantiator/src/Doctrine/Instantiator',
),
'Doctrine\\Common\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache',
),
'Doctrine\\Common\\Annotations\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/annotations/lib/Doctrine/Common/Annotations',
),
'Doctrine\\Common\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/common/lib/Doctrine/Common',
),
'DeepCopy\\' =>
array (
0 => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy',
),
'Cron\\' =>
array (
0 => __DIR__ . '/..' . '/mtdowling/cron-expression/src/Cron',
),
'Carbon\\' =>
array (
0 => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon',
),
'App\\' =>
array (
0 => __DIR__ . '/../..' . '/app',
),
);
public static $prefixesPsr0 = array (
'P' =>
array (
'Prophecy\\' =>
array (
0 => __DIR__ . '/..' . '/phpspec/prophecy/src',
),
'Parsedown' =>
array (
0 => __DIR__ . '/..' . '/erusev/parsedown',
),
),
'M' =>
array (
'Mockery' =>
array (
0 => __DIR__ . '/..' . '/mockery/mockery/library',
),
),
'J' =>
array (
'JakubOnderka\\PhpConsoleHighlighter' =>
array (
0 => __DIR__ . '/..' . '/jakub-onderka/php-console-highlighter/src',
),
'JakubOnderka\\PhpConsoleColor' =>
array (
0 => __DIR__ . '/..' . '/jakub-onderka/php-console-color/src',
),
),
'D' =>
array (
'Doctrine\\DBAL\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/dbal/lib',
),
'Doctrine\\Common\\Lexer\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/lexer/lib',
),
'Doctrine\\Common\\Inflector\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/inflector/lib',
),
'Doctrine\\Common\\Collections\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/collections/lib',
),
),
);
public static $classMap = array (
'AlterArticleColumnTitleLength' => __DIR__ . '/../..' . '/database/migrations/2017_05_04_062111_alter_article_column_title_length.php',
'App\\Article' => __DIR__ . '/../..' . '/app/Article.php',
'App\\Console\\Kernel' => __DIR__ . '/../..' . '/app/Console/Kernel.php',
'App\\Exceptions\\Handler' => __DIR__ . '/../..' . '/app/Exceptions/Handler.php',
'App\\Http\\Controllers\\ArticlesController' => __DIR__ . '/../..' . '/app/Http/Controllers/ArticlesController.php',
...
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit0726b6b85af134cab7b1acd212d59852::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit0726b6b85af134cab7b1acd212d59852::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInit0726b6b85af134cab7b1acd212d59852::$prefixesPsr0;
$loader->classMap = ComposerStaticInit0726b6b85af134cab7b1acd212d59852::$classMap;
}, null, ClassLoader::class);
}
}