-
博文分类专栏
- Jquery基础教程
-
- 文章:(15)篇
- 阅读:47251
- shell命令
-
- 文章:(42)篇
- 阅读:156661
- Git教程
-
- 文章:(36)篇
- 阅读:237759
- leetCode刷题
-
- 文章:(76)篇
- 阅读:137174
-
Composer从入门到深入2018-02-06 20:38 阅读(7027) 评论(0)
一、简介
官方对composer解释如下:
composer是PHP 的一个依赖管理工具,利用 PSR以及PHP5.3 的命名空间,它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们。
说白了就是,composer会自动帮你下载,项目中需要的代码库,当然你得依据composer要求的格式来搞才行。那么,我们得需要知道,composer与PHP是什么关系?composer能够帮我们引入哪些地方的代码库?composer是如何查询代码库的?被引入的代码库是否有某种格式限制?以及composer要求以怎样的格式申明需要的代码库等。
PSR 是 PHP Standard Recommendations 的简写,由 PHP FIG 组织制定的 PHP 规范,是 PHP 开发的实践标准。
解决的问题:多人开发时,引入的代码库版本不一致、存放位置不一致、依赖关系不统一等问题。目前常见的PHP主流框架,比如Laravel 、Symfony 、CodeIgniter 3、Yii 2 等,都使用了composer。
二、composer与PHP是什么关系
Composer 是 PHP 的一个依赖管理工具,是为了方便PHP中引入代码库的一个工具,Composer 中的很多理念都借鉴自 npm 和 Bundler。
运行 Composer 需要 PHP 5.3.2+ 以上版本。
三、composer的安装
直接安装官方的安装步骤来就可以了,就不在这里细说了。
1、若在安装过程中遇到
If possible you should enable it or recompile php with --with-openssl
可以参考“如何解决The openssl extension is missing报错问题”
2、若在安装过程中遇到
The zlib extension is not loaded, this can slow down Composer a lot.
If possible, install it or recompile php with --with-zlib
The php.ini used by your command-line PHP is: /usr/local/php/lib/php.ini
If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple times.
其实,这个不影响composer的使用。若想安装zlib扩展,可以参考“php-7.1.8安装zlib扩展”
四、composer使用
1、依赖关系文件composer.json的配置
最开始可能,你的项目文件夹下面,并没有composer.json配置文件,没有关系,Composer工具提供了初始化的方法,直接运行下面命令:
composer init
Composer工具,就会引导你去配置,如下:
这些输入项都可以先跳过,完成初始化工作后将在项目根目录生成composer.json文件,如下:
{ "name": "dequan/test2", "authors": [ { "name": "dequan", "email": "dequan@findme.wang" } ], "require": {} }
当然你也可以,你也可以手动创建composer.json文件。
配置时候可以参考Composer 在线仓库 Packagist,来选择自己需要的代码库。比如我需要使用chart.js插件,我们可以在仓库里面搜索一下,然后查看如下:
配置文件如下:
{ "require": { "nnnick/chartjs":"v2.7.0" } }
2、执行composer install下载依赖的代码库
执行下面命令
composer install
可以看出,composer工具,已经依据composer.json配置文件,自动帮我们下载了依赖的代码库,如下:
生成了composer.lock文件以及vendor文件夹。
vendor文件夹存放了项目的依赖库。
composer.lock文件用来锁定composer的,当项目根目录下已经生成composer.lock文件时,composer工具会以composer.lock文件里面定义的为准,也就是说,当两个文件里面有相同的代码库依赖需要下载的时候,composer.lock里面的配置会覆盖composer.json里面的配置。
3、执行composer update更新依赖
如果我们觉得目前使用的代码库版本不是我们需要的,我们可以修改配置文件,然后执行composer update,当然,如果仅仅想更新部分代码库,也可以指定名称,比如更新nnnick/chartjs依赖关系,如下:
composer update nnnick/chartjs
4.如何使用composer下载的代码库
到目前为止,我们已经了解了如何下载代码库,以及更新代码库,那么如何使用代码库呢?
(1)前端代码库的使用
像上面我们使用Composer工具自动下载chartjs,我们直接在页面使用即可。
(2)php代码库的使用
比如,我们引入redis代码库(predis/predis),修改composer.json配置,并下载predis库,这样vendor下面就会有predis的库,如下:
首先,需要引入composer的加载器
require 'vendor/autoload.php';
测试代码如下:
<?PHP require 'vendor/autoload.php'; //打开redis连接 try{ //连接redis $client = new Predis\Client([ 'scheme' => 'tcp', 'host' => '127.0.0.1', 'port' => 6379, ]); $client->set('predis_version', 'v1.1.0'); //将值存在redis中 $value = $client->get('predis_version'); //从redis中取出值 var_dump($value); //输出当前值 } catch(Exception $e) { var_dump($e); }
输出结果如下:
当然,我们可以通过命令行的方式,查看redis里面是否存了该值
备注:关于Predis的使用,可以参考其官方网址
五、composer自动加载的原理
上面的案例中,我直接使用 new了一个Predis\Client的实例,那么PHP是怎么找到这个类的呢?引入的autoload.php这个文件究竟做了什么呢?composer如何实现自动加载的呢?
1、我们在项目中引入了vendor/autoload.php文件,其内容如下:
require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInited8e602789714c5a77b6d9609f69cbe0::getLoader();
2、于是我们进一步跟踪,打开vendor/composer/autoload_real.php文件,
<?php // autoload_real.php @generated by Composer class ComposerAutoloaderInited8e602789714c5a77b6d9609f69cbe0 { 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('ComposerAutoloaderInited8e602789714c5a77b6d9609f69cbe0', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInited8e602789714c5a77b6d9609f69cbe0', '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'; call_user_func(\Composer\Autoload\ComposerStaticInited8e602789714c5a77b6d9609f69cbe0::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); } } $loader->register(true); return $loader; } }
getLoader方法里面,主要做的事情有:
a、通过spl_autoload_register注册加载机制,实例化vendor/composer/ClassLoader.php类,然后注销spl_autoload_unregister的自动加载机制
b、通过PHP的版本号、HHVM_VERSION、zend_loader_file_encoded判断加密等方式来选择composer的文件加载方式
c、当$useStaticLoader为true的时候,引入vendor/composer/autoload_static.php,通过call_user_func方式调用该文件中php类的getInitializer方法,在该方法中使用了PHP的匿名函数closures,最后还是为了读取php文件所在的目录。
d、当$useStaticLoader为false的时候,是使用另外一种方式,读取需要加载php文件的配置。
e、最后调用ClassLoader.php类的register方法,如下:
可以看出,使用spl_autoload_register定义了一个加载机制,在loadClass中,判断该文件存在,就加载
includeFile就是大家耳熟能详的东东了
下面使用一张图来记录Composer加载的原理
从上图可以看出,最终还是通过spl_autoload_register函数来实现自动加载。
六、使用composer加载我们自己的类库
---待续----