漫谈PHP组件、框架、Composer那些事

什么是组件

组件是一组打包的代码,是一系列相关的类、接口和Trait,用于帮助咱们解决PHP应用中某个具体问题。例如,你的PHP应用须要收发HTTP请求,可使用现成的组件如guzzle/guzzle实现。咱们使用组件不是为了从新实现已经实现的功能,而是把更多时间花在实现项目的长远目标上。php

优秀的PHP组件具有如下特性:html

  • 做用单一:专一于解决一个问题,并且使用简单的接口封装功能
  • 小型:小巧玲珑,只包含解决某个问题所需的最少代码
  • 合做:PHP组件之间能够良好合做,组合在一块儿实现大型项目
  • 测试良好:自己提供测试,并且有充足的测试覆盖度
  • 文档完善:应该提供完善的文档,能让开发者轻易安装、理解和使用

组件 vs 框架

咱们选择框架时,要为这个框架的工具投入不少,框架一般会提供大量工具,但却没有提供咱们所需的某个工具时,痛苦就转嫁到咱们头上,咱们要寻找并集成自定义的PHP库。把第三方代码集成到框架中是件难事,由于第三方代码和框架可能没有使用相同的接口。laravel

选择框架时,咱们看中的是框架的将来,可是谁又能保证某个框架始终是完成某项工做最好的工具呢?存在多年的大型项目必须有好的表现,并且要时刻作好调整,若是选错了PHP框架,可能没法作到这一点。较旧的PHP框架可能因为缺少社区支持而变慢或过期,这些旧框架一般使用过程式代码编写,而没有使用新式的面向对象代码以及PHP的一些新特性,总之,决定是否使用PHP框架时,要考虑的事情不少。shell

庆幸的是,Laravel在这些担心方面表现良好,所以才能在众多PHP框架中脱颖而出,从某种意义上来讲,Laravel也是个基于组件开发的框架(核心组件是自身的Illuminate库,功能实现上则大量依赖第三方组件),相比Symfony而言,上手又比较简单,因此兼具了扩展性和易用性。可是,Laravel也存在一些不足,好比Laravel自身的组件不能轻易解耦,用于Laravel框架以外(可是相信这种情况会有好转,好比其数据库和队列组件就能够解耦出去)。综合来看,Laravel还是一个出色的框架,能帮组咱们快速建立强大的应用。数据库

那咱们应该使用组件仍是框架呢?答案是,使用正确的工具作正确的事,若是能经过一些PHP组件快速实现小型项目,那就使用组件,若是有多个团队成员开发大型项目,并且能从框架提供的约定准则和结构中受益,那就使用框架(若是是在纠结使用什么框架,那么选择Laravel吧,它不会让你失望),使用框架可以引导并加速项目的开发。json

使用组件

Packagist

咱们在Packagist中查找PHP组件,这个网站用于收集PHP组件,最好的PHP组件在Packagist中都能找到。服务器

好比咱们想使用一个http组件用于收发HTTP消息,在搜索框中搜索http,获得的第一个结果就是Guzzle,就用它吧。composer

Composer

Packagist是查找PHP组件的社区,Composer则是安装PHP组件的工具。Composer是PHP的依赖管理器,运行在命令行中,你告诉Composer须要哪些组件,Composer会下载并把这些组件自动加载到你的项目中,就这么简单。框架

Composer和Packagist紧密合做,若是你告诉Composer想要使用guzzlehttp/guzzle组件,Composer会从Packagist中获取guzzlehttp/guzzle组件,找到这个组件的仓库地址,肯定要使用哪一个版本,还能找出这个组件的依赖,而后把guzzlehttp/guzzle组件及其依赖下载到你的项目中。工具

此外,Composer会为项目中的全部PHP组件自动生成符合PSR标准的自动加载器,有效地抽象了依赖管理和自动加载,因此,对PHP社区来讲,Composer是最重要的附加工具,没有之一,想一想以前咱们要使用诸如include、require、spl_autoload_register来手动实现自动加载的痛苦日子,这一点也不为过。

关于Composer的安装和使用,这里不赘述,请参考Composer中文网

示例项目

下面咱们经过一个示例项目来演示如何使用Composer和组件来开发一个PHP应用,这个应用的做用是扫描一个CSV文件中的URL,找出死链,该应用会向每一个URL发HTTP请求,若是返回的HTTP状态码大于等于400,就把这个死链发给标准输出。这是一个命令行应用,开发好以后,咱们会执行这个脚本,传入csv文件的路径,在标准输出中显示死链列表。

安装组件

开始以前,先看看哪些任务可使用现有的PHP组件解决:咱们须要一个能够迭代处理csv文件数据的组件,此外还要向csv文件中的每一个URL发送HTTP请求,所以还须要一个能够发送HTTP请求并检查HTTP响应的组件。

浏览Packagist后,咱们找到guzzlehttp/guzzleleague/csv两个组件,前者用于处理HTTP消息,后者用于处理CSV数据。下面咱们在项目最顶层运行以下命令:

composer require guzzlehttp/guzzle
composer require league/csv

Composer会将依赖安装到根目录的vendor目录下,安装完成后,会在根目录下生成composer.jsoncomposer.lock文件:

composer.lock文件中会列出项目使用的全部PHP组件,以及组件的具体版本号,这实际上是锁定了项目,让项目只能使用具体版本的PHP组件。这样的好处是,composer会下载这个文件中列出的具体版本,而无论Packagist中可用的最新版本是多少,你应该把composer.lock文件归入版本控制,这样让团队成员使用的PHP版本和你同样,若是本地开发和服务器使用的PHP组件版本相同,能够尽可能下降由组件版本不一样致使的bug。

若是确实要下载最新版本的组件并更新composer.lock,可使用composer update命令。

自动加载

接下来咱们来编写应用代码,在根目录下建立一个scan.php文件,而后在该文件顶部使用require导入Composer建立的自动加载器:

require 'vendor/autoload.php';

Composer建立的自动加载器其实就是个名为autoload.php的文件,保存在vendor目录中,Composer下载各个PHP组件时,会检查每一个组件的composer.json文件,肯定如何加载该组件,获得这个信息后,Composer会在本地为该组件建立一个符合PSR标准的自动加载器。这样咱们就能够实例化项目中的任何PHP组件,这些组件按需自动加载。

编写代码

下面咱们正式使用Guzzle和CSV组件编写scan.php代码:

//使用composer自动加载器
require 'vendor/autoload.php';

//实例Guzzle Http客户端
$client = new GuzzleHttp\Client();

//打开并迭代处理CSV
$csv = League\Csv\Reader::createFromPath($argv[1]);
foreach ($csv as $csvRow) {
    try {
        //发送HTTP GET请求
        $httpResponse = $client->get($csvRow[0]);

        //检查HTTP响应的状态码
        if($httpResponse->getStatusCode() >= 400) {
            throw new Exception();
        }
    } catch (Exception $e) {
            //把死链发给标准输出
            echo $csvRow[0] . PHP_EOL;
    }
}

下面咱们在urls.csv中添加一些URL,一行一个,并且至少有一个是死链:

而后打开终端,执行scan.php脚本:

php scan.php urls.csv

咱们传入了两个参数,第一个是脚本文件scan.php的路径,另外一个是CSV文件的路径。输出以下:

原文连接:漫谈 PHP 组件、框架、Composer 那些事

相关文章
相关标签/搜索