[Composer] - Composer 简介

Composer 是什么?

Composer 是由 Jordi Boggiano 和 Nils Aderman 创造的一个现代化 PHP 依赖包管理工具,它可以帮助你管理 PHP 项目中所依赖的其他库文件,你只需要配置好 composer.json 文件,然后通过命令行来执行 composer install 即可安装项目所需要的依赖包。

依赖包是什么?

我们知道一个 PHP 项目是由许许多多的 .php 文件组成的,在 MVC 思想下我们会将功能性的方法封装起来组成类,面向对象编程大大的提高了代码的复用性,减少了程序员重复造轮子的时间。

一个 PHP 项目存在许多功能性的方法,例如发送邮件、发送短信验证码、第三方登录……诸如此类,这些功能的特点是普适性,也就是说,将它们放到任何其他项目都可以适用,那么,我们有没有什么方法可以把它们封装起来,以后如果用到同样的功能,我们只需要下载下来就可以开箱即用了!完全不需要重复开发一样的东西,对吧!

在以前,我们可能会把这些封装好的类打包起来,放在某个磁盘目录下当成自己的“小金库”,以后开发新功能如果用到这个类,直接 CTRL+C、CTRL+V 拷贝到项目下,然后 require 进来就可以直接用了。

很多第三方服务商,如阿里的短信服务都有对应的 SDK 包,这些包帮我们封装好了方法,我们只需要下载下来就可以直接使用

这是在以前的做法,然而现在我们拥有了 GitHub,我们可以直接把自己的代码上传到 GitHub 上帮我们托管,在需要的时候使用 git clone 下来即可,安全又放心。

上面例子的目的是想说,有时候我们可以找到很多现成打包好的类,下载下来直接引用到我们的项目里即可,像这样的类我们便可以称它为“依赖包”,依赖包就是别人写好并且高度封装的库,我们无需关心它们是如何实现的,只需要使用它们提供好的 API 接口即可。

举一个简单的例子,小明写了一个 QQ 登录的类库,然后上传到 GitHub 分享给其他程序员使用,小红通过搜索找到这个库,使用 clone 命令下载下来放到了自己的项目里面,这样小红就可以直接用到小明写好的类了,小红通过使用小明写好的类大大的提高了工作效率,而小明因为帮助了小红从而收获了快乐。

不过,这样也会带来新的问题,如果我们的项目用到了许多其他人写好的类库(没错,我们就是那么懒!),这样一个个 clone 下来也是十分繁琐的,如果对方的类库还在不断更新,我们 clone 下来的版本也无法同步更新,有什么方法可以化简为繁,用一个命令来把我们需要的所有包都下载下来?不仅如此,我们还希望它能把所依赖的类库同步至最新版本。

为了解决这个问题,composer 诞生了!

依赖包管理工具

正如其名,依赖包管理工具就是帮我们管理依赖包的,我们可以设想一下通过一个配置文件告诉依赖包管理工具我们需要哪些包和对应的版本,罗列出类似下面的清单:

我的项目需要以下的包:

1、小明童鞋的 QQ 登录功能(最新版)
2、小红开发的后台系统(2.0 版本)
3、小刚开发的 JWT Token (1.1 版本)
4、...

上面的清单就是我们项目所需要的依赖包,在 Composer 中我们通过配置 composer.json 文件来声明我们需要哪些包和对应的版本:

{
  "require": {
    "xiaoming/qq": "^1.7",
    "xiaohong/backend": "2.0",
    "xiaogang/jwt-token": "1.1"
  }
}

通过创建 composer.json 来告诉 composer 我们项目需要安装的依赖包,然后在命令行下执行 composer install 即可自动安装配置文件中的包。当我们需要更新依赖包版本的时候,我们可以使用 composer update,然后我们就可以得到所有依赖包最新的版本了,当然,也可以按需更新指定的包。

上面的例子,我们引入了小明童鞋的 QQ 登录功能,小红的后台系统,等等……后台系统??没错!甚至可以将一整个系统(包括有前端界面)打成依赖包,依赖包不仅仅只能是一个小的功能点,甚至是一个框架、一套项目。

Composer 安装依赖包

使用 composer 安装依赖包的方法有两种,一种是通过 composer.json 文件配置 require 字段,然后使用 composer install 或者 composer update 进行安装;除此之外,还可以手动执行 composer require 命令来安装指定的包。

示例:

# 安装最新版
composer require monolog/monolog

# 指定版本
composer require "foo/bar:1.0.0"

使用 require 命令如果不指明具体的包版本,则默认获取 lastest(最新版)。

Composer 自动加载原理

为什么 composer 下载下来的包可以被自动加载呢?

通过 composer install 或者 composer update 命令执行后,会在我们当前目录下生成 vendor 文件夹,这个文件夹下就包含了所有我们需要的包。在这个文件夹里面还包含了一个特殊的 php 文件 autoload.php,它的内容如下所示:

<?php

// autoload.php @generated by Composer

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInite6c6e5c46f19ba8ff7a0f16aafb1b721::getLoader();

这一大串的是什么呀!?

我们知道,在 PHP 中如果需要引用第三方的类,那么就需要使用 require 这样的方式把类引用到我们的项目,现在我们引用了那么多的第三方类库,这样一个个 require 也是够累的,因此 composer 帮我们创建了一个自动加载文件来引入所有的类,我们根据文件里面的路径 require_once __DIR__ . '/composer/autoload_real.php'; 找到对应的文件:

image.png

查看 autoload_real.php 文件:

image.png

原来,上面那一大串毫无规律的东西原来在这里!

之所以要生成这么一串,是为了防止命名冲突。

这个类里面帮我们引入了我们所需要的所有依赖包,因此,我们最后只需要引入一个文件即可,即 vendor/autoload.php

// 在入口文件引入 composer 自动加载
require ROOT_PATH . '/vendor/autoload.php';

现在,我们可以随意的使用依赖包中的各种类啦!

依赖的包来自哪里?

Packagist 官方网站:https://packagist.org/

分享者如果希望自己的类库文件可以让别人通过 composer require 下载,那么就需要在 Packagist 的官方网站上发布自己的包信息,一个配置好的界面如下图所示:

image.png

实际上,Packagist 并不保管你的代码,而只是将链接指向了 Github 仓库地址,所以类库的代码实际上是保存在 GitHub 上面的。

在 Packagist 上配置好以后,其他用户就可以使用 composer require 作者名/包名 的方式下载下来。

我们使用 composer 时,如果不指明具体的仓库,默认是指向 Packagist 官方仓库,由于其站点属于国外,在国内访问速度较慢。我们可以在 composer.json 将仓库改成我们国内的地址,如阿里云:

{
  "require": {
    "catfan/medoo": "^1.7",
  },
  "repositories": {
    "packagist": {
      "type": "composer",
      "url": "https://mirrors.aliyun.com/composer/"
    }
  }
}

国内仓库有很多,一般来说找那些大厂的相对比较稳定,有时候可能因为仓库挂了导致你本地无法使用 composer 安装依赖包。国内仓库的原理是通过间隔一段时间去同步最新的包信息,所以与 Packagist 官方的包会存在短暂的延迟。

一些国内比较推荐的仓库地址:

// 阿里
https://mirrors.aliyun.com/composer

// Composer 中文网
https://packagist.phpcomposer.com

Composer 的运用场景

Composer 可以说是懒人工具,我们可以从网上找到绝大多数我们需要的功能,那么是不是有可能我们只写很少的代码,全部用网络上公开的第三方依赖包?

答案是肯定的,其中最有代表性的作品莫过于 Laravel 框架,Laravel 框架是一个严重依赖 Composer 的项目,几乎所有重要的功能都是通过 composer 安装的,甚至连框架本身也能够通过 composer 命令进行安装:

composer create-project --prefer-dist laravel/laravel laravel

人有多大胆,composer 有多大产!

一个基于 Laravel 的后台系统:LaravelAdmin

通过一个命令:

composer require encore/laravel-admin

就能得到一个开箱即用的后台管理系统!

Composer 的不足之处

上面说道,Composer 带给我们许多便利之处,但它也存在不足之处,如果严重依赖 Composer 的话,那么项目的体积很容易膨胀起来,这也是为什么将 Laravel 称为“重装坦克”的原因,由于 Composer 下载下来的包通常是高度封装的,需要许许多多的 php 文件来支撑,而我们知道,一个 HTTP 请求就需要加载项目中全部的 php 文件,这样会造成极大的性能开销,所以,Composer 带给我们开发效率的提升,实际上是以牺牲性能为代价,至于如何取舍,就看使用者的需求了。

Composer 带来的风险

composer 也会带来一系列的风险,例如我们使用第三方人员开发的包,其安全性就应该被质疑,在使用第三方依赖包的时候,应该优先选择在 GitHub 上高 stars 的项目,尽管这些项目的可信度更高一点,也还是无法完全避免会带来风险。

composer 所带来的风险可能是以下几种:

具有安全隐患

某些独立人员开发的包可能未经过仔细的测试,或者存在安全性的漏洞,会给项目带来安全隐患。

开发者技术参差不齐,其代码质量也应该作为考量是否引入的依据。

无法及时更新

由于使用的是他人开发的包,如果发现 BUG 或者某些功能上的不足之处,也无法自己进行解决,只能够通过 GitHub 提交 issue 来提示开发者,而对方如果没有及时查看消息,那这个 BUG 就会一直被搁置,从而影响到你的项目。

此外,开发人员是否能维持长期的更新也是一个问题,如升级 PHP 版本之后,导致某些依赖包产生问题。

依赖包的来源被切断

如果开发者将自己上传的包删除,就会造成项目无法正常安装。

讨论

还没有人评论~