前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【译】现代化的PHP开发--Composer

【译】现代化的PHP开发--Composer

作者头像
Lemon黄
发布2019-10-08 17:48:59
7180
发布2019-10-08 17:48:59
举报
文章被收录于专栏:Lemon黄Lemon黄

名人之声

就算它工作不正常也别担心。如果一切正常,你早该失业了

——Mosher的软件工程定律

来源/https://www.startutorial.com/articles/view/modern-php-developer-composer

翻译/Lemon黄

现代化的PHP开发,一定要知道包管理,即Composer。

1 包管理

通常来说,一组代码块组成一个方法,一组方法组成一个类,一组类形成一个包(package)。

可重用的包可以放入任何一个项目中,并且无需再添加任何功能即可使用。

一个包能为客户端提供API来实现单一的目标。

包能够帮助我们的项目实现“DRY(Don't Repeat Yourself--不要重复)”,软件开发的一个原则,就是减少各种信息(代码)的重复。

在大多数情况下,包是有依赖关系的。例,当“包A”需要 “包B”才能运行时,可以说“包A”依赖于“包B”。一个包有一系列的依赖关系是很常见的(例,A依赖于B,B依赖于C)。

假设没有包管理器,我们需要做什么使得依赖于B包的A包能工作起来?当我们下载A包的源代码时,发现A依赖于B包,以致于我们又要去下载B包的源代码。找到B包的源代码后,可能A还是无法工作,因为我们还要确保下载了B包的正确版本。这种依赖的关系的故事还可以继续下去。我们只讨论一个依赖关系,如果包A有多个依赖关系或者有一系列依赖关系,真很快就会变成一个噩梦。

所以,我们需要一个包管理器,一个可以解决所有依赖关系的管理器。

2 Composer vs. PEAR

PEAR:

在Composer之前,有一个叫做 PEAR 的东西。如果你很早就开始接触PHP,那你可能知道PEAR,因为它自1999年就已经存在。

PEAR的产生也是为了能重复使用包,这和Composer是类似的。但由于以下几个原因,它并不被开发者们推崇:

  • 与Composer不同,PEAR是一个系统范畴的包管理器。当有很多个项目 ,它们共享相同的依赖项,但每一个依赖项都有不同的版本时,PEAR这种方法会造成很多混乱和挫折。
  • 为了能让你的代码被PEAR的存储库所接受,需要一定数量的UP投票。这种方式抑制减缓了PEAR存储卡的增长。归根结底,开发者是为了编写代码,而不是为了提升代码而关注UP投票。

Composer:

Composer是PHP中应用程序级别的包管理器。它的灵感来自Node.js中的Npm和Ruby中的Bundler,是目前社区公认的包管理器。

Composer的生态系统由两部分组成:composer(用于安装包的命令行程序) 和 packagist(默认包的存储库)。

应用程序级别的包管理器意味着它以项目为基础来管理依赖项。这就很容易来管理很多个的项目,并能保持计算机的干净,因为它只将包下载到对应的项目目录中。

与PEAR不同的是,不需要获得任何的UP投票。所以,每个人都喜欢提交他们的代码包到Packagist存储库中。只要有人喜欢你的Packagist中提交的包,你就可以开始了(创作,开发package)。

Packagist

如上所述,Packagist(packagist.org)是composer的默认包存储库。截止到2015年9月,Packagist已经提供了69568个包。下一次,我们需要一个PHP包,我们很可能能在Packagist上找到我们要的包,而不用重头开始构建一个。作为开发人员,建议你用包的力量,因为它将节省你无数的时间和精力。截止到2015年9月,包装商提供了69568个包裹。

3 安装Composer

以下安装,基于MAC用户。

安装Composer的方式有两种作用域:本地作用域(也叫本地安装)和全局作用域(也叫全局安装)。根据专业的经验,我们建议在您的系统上(也就是全局安装)安装composer。毕竟,我们的系统上会有很多个PHP项目,我们很可能会使用composer来管理每个PHP项目的依赖关系。全局安装为我们节省了很多麻烦。

全局安装:

在终端(Terminal )中运行以下命令来全局安装composer:

代码语言:javascript
复制
curl -sS https://getcomposer.org/installer | php

mv composer.phar /usr/local/bin/composer

如果遇到与权限相关的任何错误,请在sudo模式下运行上面的命令(将sudo附加到每个命令)

本地安装:

在项目的根目录打开终端(Terminal )运行以下命令来本地安装composer:

代码语言:javascript
复制
curl -sS https://getcomposer.org/installer | php -- --filename=composer

有关composer的更详细的安装指南,请访问:

https://getcomposer.org/doc/00-intro.md#installation-linux-unix-osx

验证是否安装成功:

要验证是否正确安装了composer,请从安装了composer的目录运行下面的命令(如果composer是全局安装的,则在任何位置运行)。

代码语言:javascript
复制
composer about

如果看到类似于下面的输出,则说明安装成功。

代码语言:javascript
复制
Composer - Package Management for PHP
See https://getcomposer.org/ for more information.

4 使用Composer

Composer现在可以使用了,我们通过一个简单的例子来演示它的用法:

想象我们已经完成了一个完美的项目,我们希望生成模拟数据,例如,显示我们的客户的姓名和地址。如果数据是随机的,而且有意义的话,这会很酷,所以演示会看起来很真实。一种解决方案是键入一些假名称和地址,将它们存储在一个数组中,然后使用array_rand从数组中随机选择条目。正如你可能已经意识到的,这个解决方案听起来很乏味,不切实际。如果我们需要数百个用户的数据,会发生什么?我们需要一个救世主。

在Packagist上刚好有我们想要的包,这个很棒的包叫做 Faker。

接下来,我们就可以使用composer来安装 Faker。

在项目的根目录中,运行以下命令:

代码语言:javascript
复制
composer require fzaninotto/faker

composer需要几秒钟(毕竟是国外人开发的,在国内通常需要好几分钟,这个可以通过更改composer镜像来完成,大家百度一下)才能下载所需的文件。在composer下载引擎的作用下,composer从github下载faker的zip文件。除了下载所需的包,composer还将创建一些内部文件,我们稍后将对其进行研究。

现在我们去看看我们的项目目录,我们应该能够发现一些新创建的文件夹和文件,如下所示:

  • composer.json
  • composer.lock
  • vender

composer.json:

这个文件用来描述项目的依赖项。这是一个简单的json文件,向我们展示项目中安装了哪些包。

无论何时在命令行中运行composer require 命令,composer.json和composer.lock文件都将自动更新以反映项目中包的更改。

相反,如果将包添加到composer.json文件,则要运行 composer install 命令来下载新的包。如果要将所有包的版本更新为其版本约束指定的最新版本,可以运行composer update。如果要将所有包的版本更新为其版本约束指定的最新版本,可以运行composer update。

这就是composer的三个基本命令:

composer require:

这个命令用于将单个包添加到项目依赖项中。只要我们需要一个新的包,我们就可以运行它。这个真的很方便,因为我们根本不需要接触 composer.json文件。

此命令的另外一个用法是更新现有包的版本。例如,我们使用 composer require fzaninotto/faker 就已经安装了Faker的最新版本,如果我们不指定它的版本约束,则下载的是包的最新版本。但是我们的应用与Faker 1.4.0的版本无法兼容,我们需要Faker 1.2.0的版本,这时候我们就可以使用命令:composer require fzaninotto/faker:1.2 0,来安装。它将会下载我们指定的版本并相应更新项目中composer的相关文件。

composer install:

这个命令运行,首先会查找项目中是否有composer.lock文件,如果文件存在,则安装按文件中定义的包的确切版本,然后忽略composer.json文件。如果不存在,该命令将检查composer.json文件中定义的包,并下载与提供的版本约束匹配的包的最新版本。你能看出区别吗?使用composer.lock时,会下载准确的版本,而使用composer.json时,composer将始终尝试检索与提供的版本约束匹配的包的最新版本。当版本约束被定义为一个确切的数字时,两个动作都有相同的结果。然而,这种情况很少发生。

当我们的一个新的项目中已经定义了依赖项列表,当我们在这个项目中运行这个命令,这个命令回去安装所有列出的依赖项的包。或者我们从github上去下载别人的项目,在项目中运行此命令,也会自动下载项目中所列的依赖项的包。

在某些部署策略中,我们在生产环境中运行此命令,以便在从存储库中提取应用程序的源代码后来安装该应用程序。

composer update:

这个命令与composer install 不同,此命令此读取composer.json文件。它将现有的包更新到与composer.json文件中定义的提供的版本约束相匹配的最新版本。

我们可以使用这个命令来更新现有包的版本,类似于composer require。不同的是composer require不需要我们手动触发composer.json文件,它感觉更直观。

这个命令只从composer.json读取的事实带来了一个常见的陷阱,尤其是在生产环境中使用这个命令。我们在生产环境中不应该使用这个命令,以下是为什么的原因:

如果您的应用程序在本地开发环境中与Faker 1.2.0配合得很好,则可以将代码推送到生产环境并运行composer update。

由于我们的认知有限,我们不知道Faker的最新版本已经更新到了1.4.0。所以,composer会在生产环境中下载1.4.0的版本,因为我们在composer.json中定义Faker的版本约束为“fzaninotto/faker: 1.*”。因此,生产环境包的版本和开发环境的包的版本不一致,这不是我们预期的结果。

我们建议将composer.lock与composer.json一起部署到生产环境中,并在生产环境中使用composer install安装依赖项。

composer.lock:

虽然composer.json文件允许我们使用版本约束定义所需的包,但composer.lock会跟踪项目中安装的包的确切版本。换句话说,它存储了我们项目的当前状态。这是很重要的一点。

composer install首先读取composer.lock,这使得它成为一个更安全的命令,以下是为什么的理由:

如果从项目中完全删除vender文件夹,则将删除composer下载的所有包。现在再次运行composer install,它将获得与以前相同的软件包版本。

这就引出了我们的下一点。如果我们使用的是像git这样的版本控制系统,我们应该提交composer.lock吗?

答案是“这取决于项目的需要”。大多数时候,我们希望确保每个人在任何时候都共享相同的源代码。所以我们应当提交composer.lock。这是很常见的,因为我们大多数人都和一个团队一起工作。很少有不提交composer.lock的情况发生在我们开发包(库)时,因为用户很少需要在我们的包中运行composer安装。

composer在使用命令方面给了我们很大的灵活性,但是我们需要有以下一些规则来防止出现不必要的麻烦:

  • composer install是我们的朋友——在生产部署使用它。

一个标准的composer工作流:

  • 在composer.json中定义了一些依赖项:运行composer安装
  • 需要一个单独的包,运行:composer require some/package
  • 需要多个包:在composer.json文件中定义它们并运行composer update
  • 想要测试一个新发布的包,运行:composer require some/package:new-version
  • 准备测试发布的所有最新版本的包,运行:composer update

5 自动加载--Autoloading

在PHP中,我们可以使用了很多的include/require语句。这些语句的问题是,它们使我们的代码变得凌乱。最糟糕的是,每当我们更新目录结构时,我们都会做很多查找和替换工作。

解决方案是自动加载。它允许您定义搜索类的路径,这样就不必使用include/require手动执行。但当然,我们应该记住,实际上,自动加载仍在使用include/require。

现在,让我们回到我们的项目。有一个地方我们还没有真正探索过,那就是composer创建的vender目录。默认情况下,composer会将所有包下载到此目录。

composer实际上还生成了一个 vendor/autoload.php 的文件,该文件可以自由地为我们自动填充,使我们很容易的使用vender中的代码。

在我们的例子中,我们希望使用faker,这样我们可以简单地包含下面的文件,faker将被自动加载。

代码语言:javascript
复制
require __DIR__ . '/vendor/autoload.php';

现在,我们可以开始使用Faker:

代码语言:javascript
复制
$faker = Faker\Factory::create();
 
echo $faker->name;

6 社区的力量

你现在应该对composer有一个相当的了解。开始使用它来管理项目的依赖关系。我们保证它会使你和你的同事的生活更容易。下一次你的项目需要什么,开始在Packagist上寻找它们。拥抱社区的力量!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Lemon黄 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档