浅谈PHP组件、框架以及Composer
本篇文章主要介绍了PHP组件、框架以及Composer,具有一定的学习价值,感兴趣的朋友可以了解一下。
什么是组件
组件是一组打包的代码,是一系列相关的类、接口和Trait,用于帮助我们解决PHP应用中某个具体问题。例如,你的PHP应用需要收发HTTP请求,可以使用现成的组件如guzzle/guzzle实现。我们使用组件不是为了重新实现已经实现的功能,而是把更多时间花在实现项目的长远目标上。
优秀的PHP组件具备以下特性:
- 作用单一:专注于解决一个问题,而且使用简单的接口封装功能
- 小型:小巧玲珑,只包含解决某个问题所需的最少代码
- 合作:PHP组件之间可以良好合作,组合在一起实现大型项目
- 测试良好:本身提供测试,而且有充足的测试覆盖度
- 文档完善:应该提供完善的文档,能让开发者轻易安装、理解和使用
组件 vs 框架
我们选择框架时,要为这个框架的工具投入很多,框架通常会提供大量工具,但却没有提供我们所需的某个工具时,痛苦就转嫁到我们头上,我们要寻找并集成自定义的PHP库。把第三方代码集成到框架中是件难事,因为第三方代码和框架可能没有使用相同的接口。
选择框架时,我们看中的是框架的未来,但是谁又能保证某个框架始终是完成某项工作最好的工具呢?存在多年的大型项目必须有好的表现,而且要时刻做好调整,如果选错了PHP框架,可能无法做到这一点。较旧的PHP框架可能由于缺乏社区支持而变慢或过时,这些旧框架通常使用过程式代码编写,而没有使用新式的面向对象代码以及PHP的一些新特性,总之,决定是否使用PHP框架时,要考虑的事情很多。
庆幸的是,Laravel在这些担忧方面表现良好,因此才能在众多PHP框架中脱颖而出,从某种意义上来说,Laravel也是个基于组件开发的框架(核心组件是自身的Illuminate库,功能实现上则大量依赖第三方组件),相比Symfony而言,上手又比较简单,所以兼具了扩展性和易用性。但是,Laravel也存在一些不足,比如Laravel自身的组件不能轻易解耦,用于Laravel框架之外(但是相信这种状况会有好转,比如其数据库和队列组件就可以解耦出去)。综合来看,Laravel仍是一个出色的框架,能帮组我们快速创建强大的应用。
那我们应该使用组件还是框架呢?答案是,使用正确的工具做正确的事,如果能通过一些PHP组件快速实现小型项目,那就使用组件,如果有多个团队成员开发大型项目,而且能从框架提供的约定准则和结构中受益,那就使用框架(如果是在纠结使用什么框架,那么选择Laravel吧,它不会让你失望),使用框架能够引导并加速项目的开发。
使用组件
Packagist
我们在Packagist中查找PHP组件,这个网站用于收集PHP组件,最好的PHP组件在Packagist中都能找到。

比如我们想使用一个http组件用于收发HTTP消息,在搜索框中搜索http,得到的第一个结果就是Guzzle,就用它吧。
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/guzzle和league/csv两个组件,前者用于处理HTTP消息,后者用于处理CSV数据。下面我们在项目最顶层运行如下命令:
composer require guzzlehttp/guzzle
composer require league/csv
Composer会将依赖安装到根目录的vendor目录下,安装完成后,会在根目录下生成composer.json和composer.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相关知识请关注我的专栏PHPzhuanlan.zhihu.com
浅谈PHP组件、框架以及Composer的更多相关文章
- 浅谈JAVA集合框架
浅谈JAVA集合框架 Java提供了数种持有对象的方式,包括语言内置的Array,还有就是utilities中提供的容器类(container classes),又称群集类(collection cl ...
- [转]浅谈Python web框架
说到web framework,Ruby的世界Rails一统江湖,而Python则是一个百花齐放的世界,各种micro-framework.framework不可胜数,不完全列表见:http://wi ...
- 浅谈Python web框架
一.Python web框架 Web Framework,Ruby的世界Rails一统江湖,而Python则是一个百花齐放的世界,各种micro-framework.framework不可胜数,不完全 ...
- 【原】从一个bug浅谈YUI3组件的资源加载
篇前声明:为了不涉及业务细节,篇内信息统一以某游戏,某功能代替 前不久,某游戏准备内测客户端,开发人员测试过程中发现某功能突然不灵了,之前的测试一切ok,没有发现任何异常,第一反应是,游戏内浏览器都是 ...
- Vue 浅谈前端js框架vue
Vue Vue近几年来特别的受关注,三年前的时候angularJS霸占前端JS框架市场很长时间,接着react框架横空出世,因为它有一个特性是虚拟DOM,从性能上碾轧angularJS,这个时候,vu ...
- 【APS.NET 框架系列】浅谈ASP.NET 框架
本篇文章稍微偏原理且底层,有一定难度和且比较晦涩. 本篇文章主要是从广度上概括一下,具体的更细粒度的,会在后续的文章中,结合具体的Demo实例分析. 一 .NET框架概述 1.作用:提供了基于. ...
- 浅谈ASP.NET框架
本篇文章更适合具有一定开发经验,一定功底,且对底层代码有所研究的朋友!!! 本篇文章稍微偏原理且底层,有一定难度和且比较晦涩,文章粒度稍微粗些,更细粒度的,会在后续的文章中,结合具体的Demo实 ...
- 浅谈Log4j2日志框架及使用
目录 1.日志框架 2.为什么需要日志接口,直接使用具体的实现不就行了吗? 3.log4j2日志级别 4.log4j2配置文件的优先级 5.对于log4j2配置文件的理解 6.对于Appender的理 ...
- 浅谈前端三大框架Angular、react、vue
每个框架都不可避免会有自己的一些特点,从而会对使用者有一定的要求,这些要求就是主张,主张有强有弱,它的强势程度会影响在业务开发中的使用方式. 一.Angular,它两个版本都是强主张的,如果你用它,必 ...
随机推荐
- 1011 World Cup Betting
Title:1011 World Cup Betting 1. 注意点 比较简单,没有注意点 2. python3代码 def func(output): max = 0 index = -1 lin ...
- Python学习(五)—— 集合和字符格式化
数据类型和变量的总结 字符串 数字 列表 元组 字典 分类 1.可变不可变: 可变(即修改变量值以后id不改变):列表.字典 不可变(即修改变量值以后id改变):字符串.数字.元组 2.访问顺序: 直 ...
- 20-02-27 hive表的几个问题
1.hive表的动态分区 2.hive 表如何修改列名 3.group by 对统计指标的影响 (group by 的本质) 4.row_number 对数据的影响
- 分布式事务 --- BASE 理论
部分图片总结出自参考资料 问题 : Base 理论为什么会被提出,动机是什么 Base 和 ACID 的区别与联系 概述 上一篇我们知道CAP 理论,也知道由于现实中网络等原因,分区容错性这一元素大多 ...
- ICCV2019 oral:Wavelet Domain Style Transfer for an Effective Perception-distortion Tradeoff in Single Image Super-Resolution
引言 基于低分辨率的图像恢复高分辨图像具有重要意义,近年来,利用深度学习做单张图像超分辨主要有两个大方向:1.减小失真度(distortion, 意味着高PSNR)的图像超分辨,这类方法主要最小化均方 ...
- Fluent_Python_Part4面向对象,09-pythonic-obj,Python风格的对象
第四部分第9章,Python风格的对象 这一章接第1章,说明常见的特殊方法实现. 本章包括以下话题: 支持用于生成对象其它表示形式的内置函数(如repr().bytes(),等等) 使用一个类方法实现 ...
- ASP.NET(C#) Json序列化反序列化帮助类Jsonhelper
原文地址:https://ken.io/note/csharp-asp.net-jsonhelper using System; using System.Collections.Generic; u ...
- numpy常用函数之arange函数
2.np.arange([start, ]stop, [step, ]dtype=None) 作用: arange函数用于创建等差数组 start:可忽略不写,默认从0开始;起始值 stop:结束 ...
- 吴裕雄 Bootstrap 前端框架开发——简介
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- Mobility Express部署外部镜像服务器
1.当我们部署完ME的时候,发现有一些AP虽然显示已经加入了WLC(ME),但是它其实并没有正常的工作,显示不可用: (Cisco Controller) >show ap su Number ...