附录A:让生活变得轻松的工具

我们在本书中介绍了很多内容,从 PHP 7 的新特性开始,到编程的最佳技巧。在每一章中,我们都使用并讨论了一些工具,但由于章节和全书篇幅有限,我们没有对这些工具进行太详细的介绍。在本附录中,我们将更详细地讨论其中的三个工具。我们将讨论的工具如下:

  • Composer

  • Git

  • Grunt watch

Composer-PHP 依赖管理工具

Composer 是一款 PHP 依赖关系管理工具,它能让我们为 PHP 应用程序定义依赖关系,并由 Composer 对其进行安装/更新。Composer 完全由 PHP 编写,是 PHP Archive (PHAR) 格式的应用程序。

Composer 从 https://packagist. org/ 下载依赖项。只要 Packagist 上有,应用程序的任何依赖项都可以通过 Composer 安装。此外,如果完整的应用程序在 Packagist 上可用,也可通过 Composer 安装。

Composer 安装

Composer 是一种命令行工具,可以在操作系统中全局安装,也可以将 composer.phar 文件放在应用程序的根目录下,然后通过命令行执行。Windows 系统提供了一个可执行的安装文件,可用于全局安装 Composer。在本书中,我们将按照 Debian/Ubuntu 的说明进行全局安装。执行以下步骤:

  1. 发出以下命令下载 Composer 安装程序。文件名为安装程序,安装后只能通过以下代码用 PHP 执行:

    Wget https://getcomposer.org/installer
  2. 发出以下命令在 Debian 或 Ubuntu 上全局安装它:

    Php install --install-dir=/usr/local/bin --filename=composer

    该命令将下载 Composer,并将其安装在 /usr/local/bin 目录中,文件名为 composer。现在,我们可以全局运行 Composer 了。

  3. 通过在终端中发出以下命令来验证 Composer 安装:

    Composer --version

    如果显示 Composer 版本,则全局 Composer 安装成功。

    如果 Composer 安装在本地应用程序中,那么我们就会有一个 composer.phar 文件。命令是一样的,但所有命令都应使用 PHP 执行。例如,php composer.phar --version 将显示 Composer 的版本。

至此,Composer 已安装成功并可以运行;是时候使用它了。

使用 Composer

要在项目中使用 Composer,我们需要一个 composer.json 文件。该文件包含项目所需的所有依赖项和一些其他元数据。Composer 使用该文件来安装和更新不同的库。

假设我们的应用程序需要以不同方式记录不同信息。为此,我们可以使用 monolog 库。首先,我们将在应用程序根目录下创建一个 composer.json 文件,并添加以下代码:

{
    "require": {
      "monolog/monolog": "1.0.*"
    }
}

保存文件后,执行以下命令安装应用程序的依赖项:

Composer install

该命令将下载依赖项并将其放入供应商目录,如下截图所示:

image 2023 11 06 11 17 48 267

如上截图所示,monolog 1.0.2 版本已下载,并创建了一个供应商目录。monolog 库就放在这个目录中。此外,如果软件包需要自动加载信息,Composer 会将库放入 Composer 自动加载器,该加载器也位于供应商目录中。因此,任何新库或依赖库都会在应用程序执行过程中自动加载。

此外,还可以看到一个新文件,即 composer.lock。当 Composer 下载并安装任何依赖项时,确切的版本和其他信息都会写入该文件,以便将应用程序锁定为该特定版本的依赖项。这样可以确保所有团队成员或想要设置应用程序的人都使用完全相同版本的依赖项,从而减少使用不同版本依赖项的机会。

如今,Composer 被广泛用于软件包管理。Magento、Zend Framework、Laravel、Yii 等大型开源项目都可以通过 Composer 轻松安装。我们将在下一个附录中使用 Composer 安装其中一些项目。

Git- 版本控制系统

Git 是使用最广泛的版本控制系统。根据 Git 官方网站的介绍,它是一个分布式版本控制系统,能够快速高效地处理从小型到大型的所有项目。

Git安装

Git 适用于所有主流操作系统。Windows 系统提供了一个可执行的安装文件,可用于安装 Git 并在命令行中使用。在 OS X 上,Git 已经安装,但如果找不到,可以从其官方网站下载。在 Debian/Ubuntu 上安装 Git,只需在终端发出以下命令即可:

sudo apt-get install git

安装完成后,执行以下命令检查是否正确安装:

git –version

然后,我们将看到当前安装的 Git 版本。

使用 Git

为了更好地了解 Git,我们将从一个测试项目开始。我们的测试项目名为 packt-git。我们还为该项目创建了一个名为 packt-git 的 GitHub 仓库,并将项目文件推送到该仓库。

首先,我们将在项目中初始化 Git,命令如下:

git init

前面的命令将在我们的项目根目录下初始化一个空的 Git 仓库,头部将保留在 master 分支上,这是每个 Git 仓库的默认分支。它将创建一个隐藏的 .git 目录,其中包含有关该仓库的所有信息。接下来,我们将添加一个在 GitHub 上创建的远程仓库。我在 GitHub 上创建了一个测试仓库,URL 是 https://github.com/altafhussain10/packt-git.git。

现在,发出以下命令将 GitHub 存储库添加到我们的空存储库中:

git remote add origion https://github.com/altafhussain10/packt-git.git

现在,在项目根目录下创建一个 README.md 文件,并在其中添加一些内容。README.md 文件用于显示 Git 仓库的信息和其他细节。该文件还用于显示有关如何使用该版本库和/或创建该版本库的项目的说明。

现在,请执行以下命令查看 Git 仓库的状态:

git status

该命令将显示版本库的状态,如下截图所示:

image 2023 11 06 11 34 54 514

从前面的截图中可以看到,我们的版本库中有一个尚未提交的未跟踪文件。首先,我们将在终端发出以下命令,添加要跟踪的文件:

git add README.md

git add 命令使用工作树中的当前内容更新索引。该命令会添加路径上的所有改动。还有一些选项可以用来添加一些特定的改动。我们之前使用的命令只会将 README.md 文件添加到版本库的跟踪中。因此,如果我们想跟踪所有文件,就会使用下面的命令:

git add

这将开始跟踪当前工作目录或当前分支根目录下的所有文件。现在,如果我们想跟踪某些特定文件,例如所有扩展名为 .php 的文件,可以按如下方式使用它:

git add '*.php

这将把所有扩展名为 .php 的文件添加到跟踪中。

接下来,我们将使用以下命令向版本库提交更改或添加内容:

git commit –m "Initial Commit"

git commit 命令会将所有改动提交到本地仓库。-m 标志指定了要提交的任何日志信息。请记住,改动只会提交到本地仓库。

现在,我们将使用以下命令把更改推送到远程仓库:

git push –u origion master

上述命令将把本地版本库中的所有更改推送到远程版本库或原点。-u 标志用于设置上游,并将本地版本库链接到远程中央版本库。由于我们是第一次推送修改,所以必须使用 -u 选项。之后,我们就可以使用下面的命令了:

git push

这会将所有更改推送到我们所在的当前分支的主存储库。

创建新分支并合并

开发过程中总是需要新的分支。如果需要做任何修改,最好为这些修改创建一个新的分支。然后,在该分支上进行所有修改,最后提交、合并并推送到远程源。

为了更好地理解这一点,假设我们要修复登录页面中的一个问题。这个问题是关于验证错误的。我们将把新分支命名为 login_validation_errors_fix。给分支起一个更容易理解的名字是个好习惯。此外,我们希望从主分支头创建这个新分支。这意味着我们希望新分支继承主分支的所有数据。因此,如果我们不在主分支,就必须使用以下命令切换到主分支:

git checkout master

无论我们在哪个分支,前面的命令都会将我们切换到主分支。要创建分支,请在终端中发出以下命令:

git branch login_validation_errors_fix

现在,我们的新分支是从主分支头创建的,因此所有更改都应在这个新分支上进行。完成所有更改和修复后,我们必须将更改提交到本地和远程版本库。注意,我们没有在远程版本库中创建新分支。现在,让我们使用以下命令提交更改:

git commit -a -m "Login validation errors fix"

请注意,我们没有使用 git add 添加改动或新添加的内容。为了自动提交改动,我们在提交中使用了 -a 选项,它会自动添加所有文件。如果使用的是 git add,则无需在 commit 中使用 -a 选项。现在,我们的修改已提交到本地仓库。我们需要将修改推送到远程源。在终端中发出以下命令:

git push -u origion login_validation_errors_fix

上述命令将在远程仓库创建一个新分支,将同一本地分支的跟踪设置为远程分支,并将所有更改推送到该分支。

现在,我们要将更改与主分支合并。首先,我们需要使用以下命令切换到主分支:

git checkout master

接下来,我们将发出以下命令将新分支 login_validation_errors_fixmaster 分支合并:

git checkout master
git merge login_validation_errors_fix
git push

重要的是要切换到我们要合并新分支的分支。之后,我们需要使用 git merge branch_to_merge 语法将该分支与当前分支合并。最后,我们就可以推送到远程原点了。现在,如果我们看一下远程仓库,就会看到新分支和主分支中的改动。

克隆存储库

有时,我们需要处理一个托管在软件源上的项目。为此,我们将首先克隆这个版本库,将完整的版本库下载到本地系统,然后为这个远程版本库创建一个本地版本库。其余工作与我们之前讨论的相同。要克隆一个版本库,我们首先要知道远程版本库的网址。比方说,我们要克隆 PHPUnit 仓库。如果我们访问 PHPUnit 的 GitHub 仓库,就会在右上角看到该仓库的网址,如下面的截图所示:

image 2023 11 06 11 50 08 332

HTTPS 按钮后的 URL 就是该版本库的网址。复制该 URL 并使用以下命令克隆该版本库:

git clone https://github.com/sebastianbergmann/phpunit.git

这将开始下载软件源。下载完成后,我们将得到一个包含软件源及其所有文件的 PHPUnit 文件夹。现在,可以执行前面主题中提到的所有操作。

Webhooks

网络钩子是 Git 最强大的功能之一。网络钩子是指在仓库发生特定操作时触发的事件。如果为推送请求设置了事件或钩子,那么每次推送到该版本库时,该钩子就会被触发。

要向版本库添加 webhook,请单击右上方的版本库设置链接。在新页面的左侧,我们将看到一个 Webhooks 和服务链接。点击后,我们将看到与下图类似的页面:

image 2023 11 06 11 51 52 797

从前面的截图中可以看出,我们必须输入一个有效载荷 URL,每次选定的事件触发时都会调用该 URL。在内容类型中,我们将选择有效载荷发送到 URL 的数据格式。在 "事件 "部分,我们可以选择是只接收推送事件还是接收所有事件;我们也可以选择多个事件来触发钩子。保存钩子后,每次选定的事件发生时,钩子就会被触发。

Webhooks 主要用于部署。推送更改时,如果推送事件有 Webhook,就会调用特定的 URL。然后,该 URL 会执行一些命令来下载更改,并在本地服务器上进行处理,然后将它们放到适当的位置。此外,网络钩子还可用于继续集成和部署到云服务。

用于管理存储库的桌面工具

有几种工具可用来管理 Git 仓库。GitHub 自带的 GitHub Desktop 可用于管理 GitHub 仓库。它可以用来创建新仓库、查看历史、推送、拉取和克隆仓库。它提供了我们可以在命令行中使用的所有功能。下面的截图显示了我们的测试 packt-git 仓库:

image 2023 11 06 11 52 59 373

GitHub Desktop 可从 https://desktop. github.com/ 下载,仅适用于 Mac 和 Windows。此外,GitHub Desktop 只能与 GitHub 一起使用,除非使用一些黑客手段使它能与其他版本库(如 GitLab 或 Bitbucket)一起使用。

另一个强大的工具是 SourceTree。SourceTree 可与 GitHub、GitLab 和 Bitbucket 轻松配合使用。它提供完整的功能来管理版本库、拉取、推送、提交、合并和其他操作。SourceTree 为分支和提交提供了一个非常强大和漂亮的图表工具。以下是用于连接 packt-git 测试仓库的 SourceTree 截图:

image 2023 11 06 11 53 54 954

除了前两个不错的工具外,每个开发集成开发环境都提供版本控制系统的全面支持,还提供了一些功能,如用不同的颜色表示修改过的文件和新添加的文件。

Git 是一个功能强大的工具,不是本附录所能涵盖的。有几本书可供选择,但 Git Book 是一个很好的开始。这本书有多种格式,可从 https://gitscm.com/book/en/v2 下载,也可在线阅读。

Grunt watch

我们在第 3 章 "提高 PHP 7 应用程序性能" 中学习过 Grunt。我们只用它来合并 CSS 和 JavaScript 文件并将其最小化。然而,Grunt 并不仅仅用于此目的。它是一个 JavaScript 任务运行程序,可以通过监视特定文件的变化或手动运行任务来运行任务。我们已经学习了如何手动运行任务,现在我们将学习如何使用 grunt watch 在某些更改发生时运行特定任务。

Grunt watch 非常有用,可以节省大量时间,因为它可以自动运行特定的任务,而不是在每次更改时手动运行任务。

让我们回顾一下第 3 章 "提高 PHP 7 应用程序性能 "中的例子。我们使用 Grunt 合并并压缩 CSS 和 JavaScript 文件。为此,我们创建了四个任务。一个任务是合并所有 CSS 文件,第二个任务是合并所有 JavaScript 文件,第三个任务是压缩 CSS 文件,第四个任务是压缩所有 JavaScript 文件。如果每次修改时都手动运行所有这些任务,将非常耗时。Grunt 提供了一个名为 watch 的功能,它可以监视不同目的地的文件变化,如果发生任何变化,它就会执行 watch 中定义的任务。

首先,检查是否安装了 grunt watch 模块。检查 node_modules 目录,看是否有另一个名为 grunt-contrib-watch 的目录。如果该目录已存在,则说明 watch 已安装。如果该目录不存在,那么只需在 GruntFile.js 所在的项目根目录下的终端中发出以下命令即可:

npm install grunt-contrib-watch

前面的命令将安装 Grunt watch,grunt-contrib-watch 目录中将出现 watch 模块。

现在,我们将修改 GruntFile.js 文件,添加 watch 模块,它将监控我们定义目录中的所有文件,如果发生任何更改,它将自动运行这些任务。这将节省大量重复手动执行这些任务的时间。请看下面的代码;突出显示的代码是修改后的部分:

module.exports = function(grunt) {
    /*Load the package.json file*/
    pkg: grunt.file.readJSON('package.json'),
        /*Define Tasks*/
        grunt.initConfig({
            concat: {
                css: {
                    src: [
                        'css/*' //Load all files in CSS folder
                    ],
                    dest: 'dest/combined.css' //Destination of the final combined file.
                },//End of CSS
                js: {
                    src: [
                        'js/*' //Load all files in js folder
                    ],
                    dest: 'dest/combined.js' //Destination of the final combined file.
                }, //End of js
            }, //End of concat
            cssmin: {
                css: {
                    src : 'dest/combined.css',
                    dest : 'dest/combined.min.css'
                }
            }, //End of cssmin
            uglify: {
                js: {
                    files: {
                        'dest/combined.min.js' : ['dest/combined.js']//destination
                        Path : [src path]
                    } }
            }, //End of uglify
            //The watch starts here
            watch: {
                mywatch: {
                    files: ['css/*', 'js/*', 'dist/*'],
                    tasks: ['concat', 'cssmin', 'uglify']
                },
            },
        }); //End of initConfig
    grunt.loadNpmTasks('grunt-contrib-watch'); //Include watch module
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.registerTask('default', ['concat:css', 'concat:js',
        'cssmin:css', 'uglify:js']);
}; //End of module.exports

在前面突出显示的代码中,我们添加了一个 watch 块。mywatch 标题可以是任何名称。files 块是必需的,它接收一个源路径数组。Grunt 进程监视这些路径的变化,并执行任务块中定义的任务。此外,任务块中提到的任务已在 GruntFile.js 中创建。此外,我们还必须使用 grunt.loadNpmTasks 加载监视模块。

现在,在 GruntFile.js 所在的项目根目录下打开终端,运行以下命令:

grunt watch

Grunt 将开始监控源文件的更改。现在,在 GruntFile.js 文件块中定义的路径下修改任意文件并保存文件。文件保存后,任务将立即执行,任务的输出将显示在终端中。输出示例见下面的截图:

image 2023 11 06 11 59 46 314

可以根据需要在监视块中监视多个任务,但这些任务应存在于 GruntFile.js 中。

总结

在本附录中,我们讨论了 Composer 以及如何使用它来安装和更新软件包。此外,我们还详细讨论了 Git,包括推送、拉取、提交、创建分支和合并不同分支。此外,我们还讨论了 Git 挂钩。最后,我们讨论了 Grunt 观察,并创建了一个观察,每当 GruntFile.js 中定义的文件路径发生变化时,它就会执行四项任务。