composer是一個用PHP開發(fā)的用來管理項(xiàng)目依賴的工具,當(dāng)你在項(xiàng)目中聲明了依賴關(guān)系后,composer可以自動幫你下載和安裝這些依賴庫,并實(shí)現(xiàn)自動加載代碼。
安裝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
2.然后執(zhí)行運(yùn)行安裝腳本,然后會生成一個可執(zhí)行的phar包文件composer.phar(類似java中的.jar包)
[root@localhost composer]# php composer-setup.php
All settings correct for using Composer
Downloading...
Composer (version 1.8.5) successfully installed to: /root/composer/composer.phar
Use it: php composer.phar
[root@localhost composer]# ls
composer.phar composer-setup.php
3.執(zhí)行命令: php composer.phar, 顯示如下信息說明安裝成功,注意最好不要使用root賬戶來執(zhí)行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.8.5 2019-04-09 17:46:47
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
.....
- 如果想讓composer在任意目錄下都可以執(zhí)行,可以執(zhí)行命令:mv composer.phar /usr/local/bin/composer ,將 composer.phar 放到系統(tǒng)環(huán)境變量之下并重命名為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使用國內(nèi)鏡像庫
由于國內(nèi)特殊的網(wǎng)絡(luò)環(huán)境,訪問國外的官方鏡像庫往往速度很慢,甚至無響應(yīng),所以我們配置使用composer中文網(wǎng)(http://www.phpcomposer.com)提供的國內(nèi)鏡像庫,執(zhí)行以下命令即可
[lf@localhost root]$ composer config -g repo.packagist composer https://packagist.phpcomposer.com
簡單的composer.json
假設(shè)我們現(xiàn)在的項(xiàng)目根目錄為demo,并且我們的項(xiàng)目依賴 monolog(https://github.com/Seldaek/monolog) 這個php日志庫,這時我們可以在項(xiàng)目根目錄建立一個 composer.json 文件,并輸入以下內(nèi)容:
{
"require": {
"monolog/monolog": "1.0.*"
}
}
然后輸入命令 composer install,composer會幫我們自動下載monolog庫,一般依賴庫會默認(rèn)放在項(xiàng)目的vendor目錄下
[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的自動加載
composer不僅僅幫我們處理依賴,還幫我們實(shí)現(xiàn)了自動加載。在vendor目錄下有一個autoload.php, 只要在我們的項(xiàng)目中引入這個文件就可以自動加載依賴庫。
項(xiàng)目根目錄下新建一個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!");
測試是否運(yùn)行正常:
[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
[2021-11-03 00:32:27] demo.WARNING: this is a warning log! [] []
可以看到monolog庫完全不需要我們手動去加載,只需要使用正確的命名空間,composer的自動加載機(jī)制會幫我們找到對應(yīng)的文件并加載。
對于依賴庫,composer幫我們處理好了自動加載,那對于我們自己的項(xiàng)目文件該怎么實(shí)現(xiàn)自動加載呢,比如現(xiàn)在在我的項(xiàng)目根目下創(chuàng)建一個 controllers 目錄存放控制器,并在該目錄下新建一個Controller.php, 代碼如下:
<?php
namespace controllers;
class Controller
{
public function test()
{
echo "Controller::test\n";
}
}
現(xiàn)在如何在index.php中自動加載這個 Controller 類呢,如果我們直接在index.php寫
<?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的自動加載機(jī)制。
composer支持四種自動加載的方式:PSR-0 / PSR-4 /Classmap / Files , 其中 PSR-4 是當(dāng)前推薦的加載方式。
什么是 PSR ?
PSR 是 PHP Standards Recommendations(PHP 標(biāo)準(zhǔn)建議)的縮寫,這是一個叫做 PHP Framework Interop Group(http://www.php-fig.org/) 的組織所推出的關(guān)于PHP編程方面的一些標(biāo)準(zhǔn)建議,這個組織的成員包括一些知名的框架和項(xiàng)目,比如 CakePHP,Drupal,Magento,Symfony,Yii framework,Zend Framework 2等等,當(dāng)然也包括這里說的 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/)是關(guān)于自動加載方面做出的一些規(guī)范
- Files 是最簡單的加載方式,這種方式不管加載的文件是否用到始終都會加載,而不是按需加載
修改項(xiàng)目根目下的composer.json, 加入 "autoload" 項(xiàng):
{
"require": {
"monolog/monolog": "1.0.*"
},
"autoload": {
"files": ["controllers/Controller.php"]
}
}
需要加載哪個文件,直接寫入文件路徑即可,路徑相對項(xiàng)目的根目錄。然后執(zhí)行composer dump-autoload,該命令可以遍歷我們項(xiàng)目根目錄以及各依賴庫下的 composer.json 文件然后重新生成 vendor/composer/autoload_* 跟自動加載相關(guān)的配置文件
[root@localhost demo]# composer dump-autoload
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Generating autoload files
此時composer會幫我們更新自動加載相關(guān)的配置文件,composer dump-autoload 之后composer會把配置值寫入與 Files加載方式對應(yīng)的 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',
);
此時再運(yùn)行index.php就一切正常了
[root@localhost demo]# php index.php
Controller::test
- Classmap 加載方式也很簡單,composer會搜尋我們指定的目錄或文件,并把搜尋到的結(jié)果寫到Classmap對應(yīng)的 vendor/composer/autoload_classmap.php 配置文件中。 修改composer.json :
{
"require": {
"monolog/monolog": "1.0.*"
},
"autoload": {
"classmap": ["controllers/"]
}
}
以上配置會讓composer搜尋 controllers 目錄下的所有類,并生成配置文件,同樣先 composer dump-autoload 下:
[root@localhost demo]# composer dump-autoload
Do not run Composer as root/super user! See https://getcomposer.org/root for details
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',
);
此時發(fā)現(xiàn)之前生成的 vendor/composer/autoload_files.php 配置文件也被 composer 刪除了(由于項(xiàng)目中沒再使用到Files的加載方式)
[root@localhost demo]# ll vendor/composer/
總用量 44
-rw-r--r-- 1 root root 222 11月 03 01:59 autoload_classmap.php
-rw-r--r-- 1 root root 210 11月 03 01:59 autoload_namespaces.php
-rw-r--r-- 1 root root 143 11月 03 01:59 autoload_psr4.php
-rw-r--r-- 1 root root 1762 11月 03 01:59 autoload_real.php
-rw-r--r-- 1 root root 867 11月 03 01:59 autoload_static.php
-rw-r--r-- 1 root root 13451 11月 03 01:59 ClassLoader.php
-rw-r--r-- 1 root root 1375 11月 03 01:59 installed.json
-rw-r--r-- 1 root root 1070 11月 03 01:59 LICENSE
測試結(jié)果:
[root@localhost demo]# php index.php
Controller::test
- PSR-0 ,這種加載方式已經(jīng)過時,所以不推薦在新項(xiàng)目中使用,請用 PSR-4 來代替它。
修改composer.json 如下, 然后執(zhí)行composer dump-autoload
{
"require": {
"monolog/monolog": "1.0.*"
},
"autoload": {
"psr-0": {"controllers\\": ""}
}
}
以上配置的意思是指定 controllers命名空間 所在的父級目錄,由于controllers命名空間所在的父級目錄就是項(xiàng)目根目錄, 所以配置值用 "" ,composer dump-autoload后配置會寫入 PSR-0對應(yīng)的 vendor/composer/autoload_namespaces.php 配置文件中,而且從配置文件中可以看到之前使用的 monolog 也是使用 遵循PSR-0 規(guī)范的自動加載
[root@localhost demo]# composer dump-autoload
Do not run Composer as root/super user! See https://getcomposer.org/root for details
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
- PSR-4 是 PSR-0 的升級版,是目前推薦的自動加載方式,這種方式使用的是按需加載。
修改composer.json 如下:
{
"require": {
"monolog/monolog": "1.0.*"
},
"autoload": {
"psr-4": {"controllers\\": "controllers/"}
}
}
注意和PSR-0 的 composer.json 做對比,PSR-4 和 PSR-0 的主要區(qū)別是,PSR-4指定的就當(dāng)作當(dāng)前命名空間的目錄, 而PSR-0 指定的是當(dāng)前命名空間的父目錄。composer dump-autoload 一下, 配置會寫入PSR-4對應(yīng)的 vendor/composer/autoload_psr4.php 文件中
[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