PHP 集成和分配模块详解

在前面的几章中,我们以模块化的方式构建了一个简单的 web shop 应用程序。每个模块在处理单个位和块时都扮演着特殊的角色,这些位和块添加到整个应用程序中。应用程序本身虽然是以模块化方式编写的,但保存在 Git 单一版本控制存储库中。如果每个模块都在其自己的存储库中提供,那么分离就会干净得多。这样,我们将能够将不同的模块开发保持为完全不同的项目,同时仍然能够将它们一起使用。在我们前进的过程中,我们将看到如何通过 GIT 和 Composer 以两种不同的方式实现这一点。

在本章中,我们将介绍以下工具和服务:

Git 版本控制最初由 Linus Torvalds 发起,目前是最流行的版本控制系统之一。大型项目的总体速度和效率,以及强大的分支系统,使其在开发人员中广受欢迎。

学习 Git 版本控制本身超出了本书的范围,推荐阅读Pro Git一书。

提示

由 Scott Chacon 和 Ben Straub 编写并由 Apress 出版的Pro Git书在免费提供 https://git-scm.com/book/en/v2

作为本章的一部分,我们感兴趣的 Git 的一个简洁特性是它的子模块。它们使我们能够将更大的模块化项目(如我们的 web shop 应用程序)分割成一系列更小的子模块,而每个子模块本身就是一个 Git 存储库。

Git 出现后的三年内,GitHub 出现了。GitHub 基本上是一个构建在 Git 版本控制系统之上的 web 服务。它使开发人员能够轻松地在线发布代码,其他人可以简单地克隆他们的存储库并使用他们的代码。在 GitHub 上创建帐户是免费的,可以按照其官方主页(上的说明进行 https://github.com )。

目前,我们的应用程序的结构如下图所示:

Understanding GitHub

我们要做的是将其拆分为六个不同的 Git 存储库,如下所示:

  • core
  • catalog
  • customer
  • payment
  • sales
  • shipment

core存储库包含除src/Foggyline目录内容以外的所有内容。

假设我们在 GitHub 上创建了一个空的core存储库,并且我们的本地一体式应用程序当前保存在shop目录中,我们在计算机上初始化以下命令:

cp -R shop core-repository
rm -Rfcore-repository/.git/
rm -Rfcore-repository/src/Foggyline/*
touch core-repository/src/Foggyline/.gitkeep
cd core-repository
git init
git remote add origin git@github.com:<user>/<core-repository>.git
git add --all
git commit -m "Initial commit of core application"
git push origin master

在这一点上,我们只是将我们的一体式 web shop 应用程序的核心应用程序部分推送到 GitHub 上的core存储库中。src/Foggyline/目录中不包含任何模块。

现在,让我们回到 GitHub,为五个模块中的每一个创建一个适当的空存储库,即,catalogcustomerpaymentsalesshipment。我们现在可以为每个模块执行一组控制台命令,如以下CatalogBundle示例所示:

cp -R shop/src/Foggyline/CatalogBundle catalog-repository
cd catalog-repository
git init
git remote add origin git@github.com:<user>/<catalog-repository>.git
git add --all
git commit -m "Initial commit of catalog module"
git push origin master

将所有五个模块推送到存储库后,我们最终可以将它们视为子模块,如下所示:

cd core-repository
git submodule add git@github.com:<user>/<catalog-repository>.git src/Foggyline/CatalogBundle
git submodule add git@github.com:<user>/<customer-repository>.git src/Foggyline/CustomerBundle
git submodule add git@github.com:<user>/<payment-repository>.git src/Foggyline/PaymentBundle
git submodule add git@github.com:<user>/<sales-repository>.git src/Foggyline/SalesBundle
git submodule add git@github.com:<user>/<shipment-repository>.git src/Foggyline/ShipmentBundle

如果我们现在在core存储库目录中运行ls-al命令,我们应该能够看到其中包含以下内容的.gitmodules文件:

[submodule "src/Foggyline/CatalogBundle"]
 path = src/Foggyline/CatalogBundle
url = git@github.com:<user>/<catalog-repository>.git

[submodule "src/Foggyline/CustomerBundle"]
 path = src/Foggyline/CustomerBundle
url = git@github.com:<user>/<customer-repository>.git

[submodule "src/Foggyline/PaymentBundle"]
 path = src/Foggyline/PaymentBundle
url = git@github.com:<user>/<payment-repository>.git

[submodule "src/Foggyline/SalesBundle"]
 path = src/Foggyline/SalesBundle
url = git@github.com:<user>/<sales-repository>.git

[submodule "src/Foggyline/ShipmentBundle"]
 path = src/Foggyline/ShipmentBundle
 url = git@github.com:<user>/<shipment-repository>.git

.gitmodules文件基本上包含添加到我们核心项目中的所有子模块的列表,即核心应用程序。我们现在应该提交并将此文件推送到core存储库。假设.gitmodules文件被推送到core存储库,我们可以轻松删除目前创建的所有目录,并通过一个简单的命令启动项目,如下所示:

git clone --recursive git@github.com:<user>/<core-repository>.git

git clone命令的--recursive参数根据.gitmodules文件自动初始化和更新存储库中的每个子模块。

Composer 是 PHP 的依赖项管理工具。默认情况下,它不会安装任何全局的东西,而是基于每个项目安装。我们可以使用它来重新分发项目,以便定义成功执行项目所需的库和包。使用 Composer 非常简单。它所创建的只是在我们项目的根目录中创建一个内容类似的composer.json文件,如下所示:

{
"require": {
"twig/twig": "~1.0"
    }
}

如果我们要在某个空目录中创建前面的composer.json文件并在该目录中执行composer install命令,Composer 将拾取composer.json文件并为我们的项目安装定义的依赖项。实际的install操作意味着将所需代码从远程存储库下载到我们的机器上。在此过程中,install命令创建composer.lock文件,该文件写入已安装依赖项的确切版本列表。

我们也可以简单地执行作曲家所需的命令twig/twig:~1.0,该命令执行相同的操作,但方法不同。它不需要我们编写一个composer.json文件,如果存在,它会更新它。

了解作曲家本身不在本书的范围之内,推荐的官方文档可在上找到 https://getcomposer.org/doc

Composer 允许打包和正式的依赖关系管理,这使得将我们的一体式模块化应用程序分割成一系列 Composer 包成为一个不错的选择。这些包需要一个存储库。

当涉及到 Composer 包时,主存储库是Packagisthttps://packagist.org )。这是一个 web 服务,我们可以通过浏览器访问它,在它上免费打开一个帐户,然后开始向存储库提交我们的包。我们还可以使用它来搜索已经存在的包。

PackageGist 通常用于免费开源软件包,但我们可以以相同的方式将privateGitHubBitBucket存储库附加到它,唯一的区别是私有存储库需要 SSH 密钥才能工作。

作曲家包装机有更方便的商业装置,如托兰代理https://toranproxy.com )。这允许更轻松地托管私有包、更快安装包所需的更高带宽以及商业支持。

到目前为止,我们将应用程序分为六个不同的 Git 存储库,一个用于核心应用程序,其余五个分别用于每个模块(catalogcustomerpaymentsalesshipment)。现在,让我们进入最后一步,看看如何从 Git 子模块转移到 Composer 包。

假设我们在上创建了账户 https://packagist.org 并成功登录后,我们将点击提交按钮开始,这将使我们进入类似于以下截图的屏幕:

Understanding Packagist

在这里,我们需要提供到现有 Git、SVN 或 Mercurial(HG)存储库的链接。前面的示例提供了一个链接(https://github.com/ajzele/B05460_CatalogBundle )到 Git 存储库。在我们按下检查按钮之前,我们需要确保我们的存储库在其根目录中定义了一个composer.json文件,否则将抛出一个类似于下面屏幕截图中所示的错误。

Understanding Packagist

然后我们将为我们的CatalogBundle创建具有以下内容的composer.json文件:

{
"name": "foggyline/catalogbundle",
"version" : "1.0.0",
"type": "library",
"description": "Just a test module for web shop application.",
"keywords": [
"catalog"
  ],
"homepage": "https://github.com/ajzele/B05460_CatalogBundle",
"license": "MIT",
"authors": [
    {
"name": "Branko Ajzele",
"email": "ajzele@gmail.com",
"homepage": "http://foggyline.net",
"role": "Developer"
    }
  ],
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-0": {
"Foggyline\\CatalogBundle\\": ""
    }
  },
"target-dir": "Foggyline/CatalogBundle"
}

这里有相当多的属性,所有这些都在上有完整的文档记录 https://getcomposer.org/doc/04-schema.md 页。

在前面的composer.json文件就位后,在控制台上运行composer install命令将在vendor/foggyline/catalogbundle目录下拉入代码,从而在vendor/foggyline/catalogbundle/Foggyline/CatalogBundle/FoggylineCatalogBundle.php下形成我们的捆绑文件的完整路径。

一旦我们将前面的composer.json文件添加到我们的 Git 存储库中,我们就可以返回 Packagist 并继续单击检查按钮,这将产生一个类似于以下屏幕截图的屏幕:

Understanding Packagist

最后,当我们点击提交按钮时,会出现一个类似以下截图的屏幕:

Understanding Packagist

我们的软件包现在已添加到 PackageGist,在 console 上运行以下命令将其安装到项目中:

composer require foggyline/catalogbundle:dev-master

类似地,我们只需将适当的条目添加到现有项目的composer.json文件中,如下代码块所示:

{
"require": {
"foggyline/catalogbundle": "dev-master"
    },
}

现在我们知道了如何跨多个 Git 存储库和 Composer 包分割应用程序,我们需要对src/Foggyline/目录中的其余模块执行相同的操作,因为只有这些模块将注册为 Composer 包。

sales模块的开发过程中,我们注意到它依赖于其他几个模块,比如catalogcustomer。我们可以使用composer.json文件的 require 属性来概述这种依赖关系。

一旦src/Foggyline/模块的所有 Git 存储库都用正确的composer.json定义进行了更新,我们就可以返回到我们的核心应用程序存储库并更新其composer.json文件中的require属性,如下所示:

{
"require": {
// ...
"foggyline/catalogbundle": "dev-master"
"foggyline/customerbundle": "dev-master"
"foggyline/paymentbundle": "dev-master"
"foggyline/salesbundle": "dev-master"
"foggyline/shipmentbundle": "dev-master"
        // ...
    },
}

在这一点上,使用子模块和包之间的区别可能并不明显。但是,与子模块不同,包允许版本控制。虽然我们所有的软件包都是从dev-master中引入的,但我们可以很容易地针对特定版本的软件包(如果有的话)。

在本章中,我们简要介绍了 Git 和 Composer,以及如何通过 GitHub 和 Packagist 将模块集成和分发为他们的服务。在 Packagist 下发布包已经被证明是一个非常简单和简单的过程。只需要一个到版本控制系统存储库的公共链接和我们项目根目录中的composer.json文件定义。

如本章所述,从头开始编写自己的应用程序并不一定意味着我们需要使用 Git 子模块或 Composer 包。Symfony 应用程序本身是通过 bundle 模块化构造的。在 Symfony 项目上使用版本控制系统时,应该只保存我们的代码,这意味着在设置项目时,所有 Symfony 库和其他依赖项都将通过 Composer 拉入。本章中所示的示例仅说明了如果我们编写了要与其他人共享的模块化组件,那么可以实现什么。举个例子,如果我们真的在开发一个健壮的catalog模块,其他对自己的网络商店编码感兴趣的人可能会发现在他们的项目中需要并使用它是很有趣的。

本书首先介绍了 PHP 生态系统的当前状态。然后,我们触及设计模式和原则,作为专业编程的基础。然后,我们开始为我们的 web shop 应用程序编写一个简短、更直观的规范。最后,我们将应用程序拆分为核心模块和其他几个较小的模块,然后按照规范进行编码。在此过程中,我们熟悉了一些最常用的 Symfony 功能。我们编写的整个应用程序远远不够健壮。这是一个最简单形式的网络商店,在功能方面还有很多需要改进的地方。然而,应用的概念展示了用 PHP 编写模块化应用程序是多么容易和快速。

教程来源于Github,感谢apachecn大佬的无私奉献,致敬!

技术教程推荐

技术领导力实战笔记 -〔TGO鲲鹏会〕

React实战进阶45讲 -〔王沛〕

Elasticsearch核心技术与实战 -〔阮一鸣〕

乔新亮的CTO成长复盘 -〔乔新亮〕

物联网开发实战 -〔郭朝斌〕

体验设计案例课 -〔炒炒〕

如何落地业务建模 -〔徐昊〕

Kubernetes入门实战课 -〔罗剑锋〕

JavaScript进阶实战课 -〔石川〕