详解composer的自动加载机制
composer是一个用PHP开发的用来管理项目依赖的工具,当你在项目中声明了依赖关系后,composer可以自动帮你下载和安装这些依赖库,并实现自动加载代码。

安装composer
composer的安装非常的容易
1.下载安装脚本,这里把安装脚本保存为 composer-setup.php
[root@localhost composer]# php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');" [root@localhost composer]# ls composer-setup.php
[root@localhost composer]# php composer-setup.php All settings correct for using Composer Downloading... Composer (version 1.5.2) successfully installed to: /root/composer/composer.phar Use it: php composer.phar [root@localhost composer]# ls composer.phar composer-setup.php
3.执行命令: php composer.phar, 显示如下信息说明安装成功,注意最好不要使用root账户来执行composer命令,否则会报警告:
Do not run Composer as root/super user! See https://getcomposer.org/root for details
[root@localhost composer]# php composer.phar Do not run Composer as root/super user! See https://getcomposer.org/root for details ______ / ____/___ ____ ___ ____ ____ ________ _____ / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/ / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ / \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/ /_/ Composer version 1.5.2 2017-09-11 16:59:25 Usage: command [options] [arguments] Options: -h, --help Display this help message .....
4. 如果想让composer在任意目录下都可以执行,可以执行命令:mv composer.phar /usr/local/bin/composer ,将 composer.phar 放到系统环境变量之下并重命名为composer, 之后便可以在任意目录使用 composer 来代替 php composer.phar 命令
[root@localhost composer]# mv composer.phar /usr/local/bin/composer [root@localhost composer]# cd ~ [root@localhost ~]# composer Do not run Composer as root/super user! See https://getcomposer.org/root for details ______ / ____/___ ____ ___ ____ ____ ________ _____ / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/ / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ / \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/ .....
配置composer使用国内镜像库
由于国内特殊的网络环境,访问国外的官方镜像库往往速度很慢,甚至无响应,所以我们配置使用composer中文网(http://www.phpcomposer.com)提供的国内镜像库,执行以下命令即可
[zyee@localhost root]$ composer config -g repo.packagist composer https://packagist.phpcomposer.com
简单的composer.json
假设我们现在的项目根目录为demo,并且我们的项目依赖 monolog(https://github.com/Seldaek/monolog) 这个php日志库,这时我们可以在项目根目录建立一个 composer.json 文件,并输入以下内容:
{ "require": { "monolog/monolog": "1.0.*" } }
[root@localhost demo]# ls composer.json [root@localhost demo]# composer install Do not run Composer as root/super user! See https://getcomposer.org/root for details Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 1 install, 0 updates, 0 removals Failed to download monolog/monolog from dist: The zip extension and unzip command are both missing, skipping. The php.ini used by your command-line PHP is: /etc/php.ini Now trying to download from source - Installing monolog/monolog (1.0.2): Cloning b704c49a30 Writing lock file Generating autoload files [root@localhost demo]# ls composer.json composer.lock vendor
composer不仅仅帮我们处理依赖,还帮我们实现了自动加载。在vendor目录下有一个autoload.php, 只要在我们的项目中引入这个文件就可以自动加载依赖库。
项目根目录下新建一个index.php, 并输入以下测试代码:
<?php require 'vendor/autoload.php'; use Monolog\Logger; use Monolog\Handler\StreamHandler; $log = new Logger('demo'); $log->pushHandler(new StreamHandler('app.log', Logger::WARNING)); $log->addWarning("this is a warning log!");
[root@localhost demo]# php index.php [root@localhost demo]# ls app.log composer.json composer.lock index.php vendor [root@localhost demo]# cat app.log [2017-09-28 00:32:27] demo.WARNING: this is a warning log! [] []
对于依赖库,composer帮我们处理好了自动加载,那对于我们自己的项目文件该怎么实现自动加载呢,比如现在在我的项目根目下创建一个 controllers 目录存放控制器,并在该目录下新建一个Controller.php, 代码如下:
<?php namespace controllers; class Controller { public function test() { echo "Controller::test\n"; } }
<?php require 'vendor/autoload.php'; use controllers\Controller; $c = new Controller(); $c->test();
上面代码肯定是无法找到Controller类的:
[root@localhost demo]# php index.php PHP Fatal error: Uncaught Error: Class 'controllers\Controller' not found in /root/demo/index.php:6 Stack trace: #0 {main} thrown in /root/demo/index.php on line 6
composer支持四种自动加载的方式:PSR-0 / PSR-4 /Classmap / Files , 其中 PSR-4 是当前推荐的加载方式。
什么是 PSR ?
PSR 是 PHP Standards Recommendations(PHP 标准建议)的缩写,这是一个叫做 PHP Framework Interop Group (http://www.php-fig.org/) 的组织所推出的关于PHP编程方面的一些标准建议,这个组织的成员包括一些知名的框架和项目,比如 CakePHP,Drupal,Magento,Symfony,Yii framework,Zend Framework 2等等,当然也包括这里说的 composer,该组织曾推出了一系列的 PSR, 具体的有哪些请参考 http://www.php-fig.org/psr/ , 其中 PSR-0 (http://www.php-fig.org/psr/psr-0/)和 PSR-4 (http://www.php-fig.org/psr/psr-4/)是关于自动加载方面做出的一些规范
1. Files 是最简单的加载方式,这种方式不管加载的文件是否用到始终都会加载,而不是按需加载
修改项目根目下的composer.json, 加入 "autoload" 项:
{ "require": { "monolog/monolog": "1.0.*" }, "autoload": { "files": ["controllers/Controller.php"] } }
[root@localhost demo]# composer update Do not run Composer as root/super user! See https://getcomposer.org/root for details Loading composer repositories with package information Updating dependencies (including require-dev) Nothing to install or update Generating autoload files
此时composer会帮我们更新加载的配置文件,composer update 之后composer会把配置值写入 与Files对应的 vendor/composer/autoload_files.php 配置文件中:
[root@localhost demo]# cat vendor/composer/autoload_files.php <?php // autoload_files.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( '0b001b283842589bdffd092a1d29de66' => $baseDir . '/controllers/Controller.php', );
[root@localhost demo]# php index.php
Controller::test
2. Classmap 加载方式也很简单,composer会搜寻我们指定的目录或文件,并把搜寻到的结果写到Classmap对应的 vendor/composer/autoload_classmap.php 配置文件中。 修改composer.json :
{ "require": { "monolog/monolog": "1.0.*" }, "autoload": { "classmap": ["controllers/"] } }
[root@localhost demo]# composer update Do not run Composer as root/super user! See https://getcomposer.org/root for details Loading composer repositories with package information Updating dependencies (including require-dev) Nothing to install or update Generating autoload files [root@localhost demo]# cat vendor/composer/autoload_classmap.php <?php // autoload_classmap.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( 'controllers\\Controller' => $baseDir . '/controllers/Controller.php', );
此时发现之前生成的 vendor/composer/autoload_files.php 配置文件也被 composer 删除了(由于项目中没再使用到Files的加载方式)
[root@localhost demo]# ll vendor/composer/ 总用量 44 -rw-r--r-- 1 root root 222 9月 28 01:59 autoload_classmap.php -rw-r--r-- 1 root root 210 9月 28 01:59 autoload_namespaces.php -rw-r--r-- 1 root root 143 9月 28 01:59 autoload_psr4.php -rw-r--r-- 1 root root 1762 9月 28 01:59 autoload_real.php -rw-r--r-- 1 root root 867 9月 28 01:59 autoload_static.php -rw-r--r-- 1 root root 13451 9月 28 01:59 ClassLoader.php -rw-r--r-- 1 root root 1375 9月 28 01:59 installed.json -rw-r--r-- 1 root root 1070 9月 28 01:59 LICENSE
测试结果:
[root@localhost demo]# php index.php
Controller::test
修改composer.json 如下, 然后执行composer update
{ "require": { "monolog/monolog": "1.0.*" }, "autoload": { "psr-0": {"controllers\\": ""} } }
[root@localhost demo]# composer update Do not run Composer as root/super user! See https://getcomposer.org/root for details Loading composer repositories with package information Updating dependencies (including require-dev) Nothing to install or update Generating autoload files [root@localhost demo]# cat vendor/composer/autoload_namespaces.php <?php // autoload_namespaces.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( 'controllers\\' => array($baseDir . '/'), 'Monolog' => array($vendorDir . '/monolog/monolog/src'), ); [root@localhost demo]# php index.php Controller::test
修改composer.json 如下:
{ "require": { "monolog/monolog": "1.0.*" }, "autoload": { "psr-4": {"controllers\\": "controllers/"} } }
[root@localhost demo]# cat vendor/composer/autoload_psr4.php <?php // autoload_psr4.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( 'controllers\\' => array($baseDir . '/controllers'), ); [root@localhost demo]# php index.php Controller::test
以上就是对composer的四种自动加载方式的简单介绍,这里主要偏向于使用,至于代码的实现,大家可以阅读 vendor/autoload.php 以及 vendor/composer/ 目录下的相关代码,有时间我再单独写一篇composer自动加载机制实现的源码分析^^
That's it!
此文为原创,转载请注明出处 :http://blog.csdn.net/zhang197093/article/details/78118491

浙公网安备 33010602011771号