PHPStorm-秘籍-全-

PHPStorm 秘籍(全)

原文:zh.annas-archive.org/md5/e01d86f28cc918b63b47eb12475bcca7

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

PhpStorm 是一个智能的 PHP 集成开发环境,它能理解你的代码和其结构。它提供代码自动完成、重构、语法高亮等功能,还有更多。PhpStorm 使得调试和测试变得非常容易,尤其是在调试器配置验证方面。

PhpStorm 烹饪秘籍 包含了几个教程,通过帮助你测试和调试,让你能够以良好的速度进行 PHP 开发,而这通常是开发者容易忽视的。

本书一开始就关注如何使用 PhpStorm 进行烹饪,为你提供 PHP 开发的概述,然后深入探讨重构和使用 PhpStorm IDE 构建项目的细节。之后,它转向集成框架和测试调试,然后转向在团队中使用 PhpStorm、使用 Phing 和烹饪插件。我们得出结论,本书将对喜欢使用 IDE 并期待更快工作的 PHP 程序员大有裨益。

本书涵盖的内容

第一章, 使用 PhpStorm 烹饪,为你快速概述了访问项目、自定义视图、移动到上一个和下一个编辑位置等内容。

第二章, PHP 开发,涵盖了 PHP 类;方法,包括获取器/设置器方法;代码块;注释等更多内容。

第三章, 重构和构建,包括重命名、复制、移动和删除元素;它还包括代码搜索、比较和设置运行配置。

第四章, 集成框架,涵盖了框架的需求以及如何使用 Symphony 和 Yii 等框架与 PhpStorm 一起工作。

第五章, 测试和调试,为你概述了安装 PHPUnit、测试应用程序、设置断点、即时更改代码等更多内容。

第六章, 在团队中使用 PhpStorm,包括创建 CVS 仓库、将 PhpStorm 连接到 CVS 仓库、提交文件、检出项目等更多内容。

第七章, PhpStorm 和 Phing,为你概述了将 Phing 连接到 PhpStorm、构建应用程序、设置 Phing 编辑器选项等内容。

第八章, 烹饪库插件,是关于验证插件、插件代码提示以及更多内容。

第九章, 代码质量分析,涵盖了混乱检测器和代码嗅探器;它还包括定位代码重复、代码格式化和重排。

你需要为本书准备的内容

本书假设你已具备 PHP 知识,并且你有一台安装了 Apache、PHP 和 PhpStorm IDE 的计算机。

本书面向的对象

本书面向所有层次的 Web 应用程序开发者,他们期待使用 PhpStorm IDE 更快、更有效地工作。它假设读者具有使用 LAMP/WAMP 环境进行 PHP 开发的先验知识;然而,本书专注于 LAMP。

部分

本书包含以下部分:

准备工作

本节告诉我们食谱中可以期待什么,并描述了为食谱设置任何软件或任何必需的初步设置的方法。

如何做…

本节描述了遵循的步骤以“烹饪”食谱。

工作原理…

本节通常包括对上一节发生情况的简要和详细说明。

更多内容…

它包含有关食谱的附加信息,以便使读者对食谱更加关注。

相关内容

本节可能包含对食谱的引用。

惯例

在本书中,您将找到许多不同风格的文章,以区分不同类型的信息。以下是一些这些风格的示例及其含义的解释。

文本中的代码单词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 昵称如下所示:“如果提供了包含路径中的文件夹,它将有助于include()require()等自动完成的完成。”

代码块如下设置:

class Dish {
/**
* @param string $dishName The name of the dish
*/
protected function addSalt(){ }
}

命令行输入或输出如下所示:

svnadmin create /path/to/your/repo/

新术语重要词汇以粗体显示。屏幕上显示的单词,例如在菜单或对话框中,在文本中显示如下:“要启用此功能,您需要选择与按字典顺序排序查找项相邻的复选框。”

注意

警告或重要注意事项以如下框的形式出现。

小贴士

小技巧和窍门如下所示。

读者反馈

我们欢迎读者的反馈。告诉我们您对这本书的看法——您喜欢什么或可能不喜欢什么。读者反馈对我们开发您真正从中受益的标题非常重要。

要发送给我们一般性的反馈,只需发送电子邮件到<feedback@packtpub.com>,并在邮件的主题中提及书名。

如果您在某个主题上具有专业知识,并且您对撰写或为书籍做出贡献感兴趣,请参阅我们的作者指南www.packtpub.com/authors

客户支持

现在您是 Packt 书籍的骄傲拥有者,我们有许多事情可以帮助您从购买中获得最大收益。

下载示例代码

您可以从www.packtpub.com的账户下载您购买的所有 Packt 书籍的示例代码文件。如果您在其他地方购买了这本书,您可以访问www.packtpub.com/support并注册,以便将文件直接通过电子邮件发送给您。

错误清单

尽管我们已经尽一切努力确保我们内容的准确性,但错误仍然可能发生。如果您在我们的某本书中发现错误——可能是文本或代码中的错误——如果您能向我们报告这一点,我们将不胜感激。通过这样做,您可以避免其他读者的挫败感,并帮助我们改进本书的后续版本。如果您发现任何勘误,请通过访问www.packtpub.com/submit-errata,选择您的书籍,点击勘误提交表单链接,并输入您的勘误详情来报告它们。一旦您的勘误得到验证,您的提交将被接受,勘误将被上传到我们的网站,或添加到该标题的勘误部分下的现有勘误列表中。您可以通过从www.packtpub.com/support选择您的标题来查看任何现有的勘误。

侵权

在互联网上对版权材料的侵权是一个跨所有媒体的持续问题。在 Packt,我们非常重视我们版权和许可证的保护。如果您在互联网上发现我们作品的任何非法副本,无论形式如何,请立即提供位置地址或网站名称,以便我们可以寻求补救措施。

请通过发送电子邮件到<copyright@packtpub.com>并附上涉嫌侵权材料的链接与我们联系。

我们感谢您在保护我们作者以及为我们带来有价值内容方面的帮助。

问题

如果您在本书的任何方面遇到问题,可以通过发送电子邮件到<questions@packtpub.com>联系我们,我们将尽力解决。

第一章. 使用 PhpStorm 烹饪

在本章中,我们将介绍以下食谱:

  • 显示/隐藏视图

  • 自定义视图

  • 访问任何项目文件

  • 最大化视图和编辑器

  • 返回上一个编辑器

  • 返回上一个编辑位置

  • 将视图链接到编辑器

  • 创建一个键绑定

  • 创建书签

  • 恢复已删除的资源

  • 使用 PhpStorm 进行自定义

  • 添加一个包含路径

  • 从索引中排除不需要的目录

  • 使用代码补全

简介

最后,你的辛勤工作将产生一些结果——你现在编写 PHP 所需的汗水将减少。你无法爱上 PHP 作为编程语言的原因从来都不是微不足道的。没有强大的 IDE 处理 PHP 的工作并不比在关闭车灯的情况下夜间驾驶轻松。人们常说 PHP 是一种弱类型语言(上帝保佑那些这么说的人!),然而 PHP 错误是噩梦般的——所有那些神秘的 500 错误、403 错误等等。

但我们不要忘记,错误代码肯定有它的意义。Apache 服务器无法将 PHP 解释为这样的,因此它给你一个提示,可能作业是不完整的,你必须查看你的 PHP 代码并自己找到确切的错误。你就像在暴风雨中一艘漏水的船上漂泊... 很悲伤!

为了能够带着一艘漏水的船从这场暴风雨中出来,你肯定需要一些帮助:一个补丁,也许是一些更好的材料,比如一个带有真正智能的编辑器;这样的智能不仅会告诉你错误,还会在解决问题上给你很大的帮助。简而言之,你需要一个智能 IDE,比如 PhpStorm,来像编程世界中的其他生物一样编写 PHP。

PhpStorm 理解程序员不是机器人,因此它不遗余力地使编码对他们来说更容易——无论是美丽的语法高亮、代码格式化、语言注入、错误检查、标记代码行,还是所有可能的思维组合。是的,PhpStorm 有解决你所有编码问题的方案,并确保你可以爱上 PHP。

PhpStorm 由 JetBrains 创建和维护,这是一个在许多其他语言中也有许多类似产品的组织。JetBrains 的人尊重每一个程序员社区,因此他们为包括 Java 在内的许多编程语言提供了 IDE。PhpStorm 使用 Java 编程语言构建,并经过精心设计,能够支持几乎所有直接或间接提供编程辅助的常见和不常见工具。

小贴士

PhpStorm 是一个智能代码编辑器,它提供智能代码补全、语法高亮、扩展代码格式配置、即时错误检查、代码折叠、支持语言混合等功能。

显示/隐藏视图

视图,正如其名所示,是 PhpStorm 中一个视觉区域,它使您,PHP 程序员,能够看到代码的各个方面和/或视角。

这包括以下内容:

  • 您辛勤劳作后的代码结构

  • 您的收藏夹(或快速查看快捷键)

  • TODO 列表形式的未来计划

  • 您整个 PHP 项目的鸟瞰图

  • 代码在本地系统以及/或版本控制系统中的更改

如何操作...

执行以下步骤:

  1. PhpStorm 中的视图可以通过以下键盘快捷键以及一些导航菜单项以及一些鼠标点击来显示/隐藏:

    视图 快捷键
    终端视图 Alt + F12
    TODO 视图 Alt + 6
    项目视图 Alt + 1
    收藏夹视图 Alt + 2
    结构视图 Alt + 7
  2. 访问这些功能的最佳快捷键位于 PhpStorm 的左下角,如下截图所示:如何操作...

它是如何工作的...

让我们一次服务一个视图,以便它们可以热腾腾地上桌:

  • 终端视图:PhpStorm 确保您不会因为任何原因而离开。如果您想进行一些命令行活动,例如运行一些 shell 命令、设置一些 cron 作业或任何其他操作,PhpStorm 内部有这个命令行终端。请记住键盘快捷键 Alt + F12

  • TODO 视图:要过程序员的日常生活,您需要多个核心处理器来限制时间;无限的云存储空间,以便无论您听到什么都会被永远记录下来;以及 32 GB 的 RAM,以便没有上下文切换将活动进程推离内存到磁盘上。简而言之,您需要成为贾维斯(钢铁侠系列)。醒来!您仍然是一个有自然倾向开始做梦并因此偏离主题、忘记主要课程的人类。

    PhpStorm IDE 中的 TODO 视图是一个功能,您可以记录您未来计划对代码进行更改。这不仅帮助您(在大多数情况下)记住您的计划,而且当需要时可以搜索它们。TODO 功能就像一张实际上占据了您工作台所有空间的便利贴。请使用 Alt + 6 在您的便利贴上。

  • 项目视图:一个项目类似于机械师的工作室,在那里以不太引人注目的方式制造出伟大的事物。您的项目包含各种注释掉的代码、示例逻辑、测试逻辑和失败的算法,这确实会在您关闭电脑、下班回家时让您微笑。在 PhpStorm 中,项目视图是一个层次视图,显示您的代码的确切层次结构以及哪些文件位于树中的哪个节点。为了显示项目视图,请使用 Alt + 1

  • 收藏夹视图:收藏夹是您需要相当频繁的项目或列表,因此 PhpStorm 提供了一种功能,可以非常容易地查找这些项目。默认情况下,PhpStorm 提供三个收藏夹:您的代码中的书签、您可能设置的代码调试器断点以及包含与您在 PhpStorm 中创建项目时相同名称的其他收藏夹项的列表。键盘快捷键是Alt + 2

  • 结构视图:还有什么比看到整个代码以统一格式更令人心情舒畅和灵魂得到慰藉的呢?PhpStorm IDE 以这种方式提供代码的结构视图,使得所有方法都显示为列表形式。这使得您能够更好地控制您创建的任何类的成员,并防止命名空间冲突和方法重复。为了打开结构视图,您只需要记住键盘快捷键Alt + 7

  • 数据库视图:尽管在编程世界中编写数据库是其中最令人畏惧的任务之一,但 PhpStorm 通过向系统中添加数据库视图来减轻这种压力。它允许您查看数据库表、存储在其中的存储过程、存储在其中的数据以及与数据库相关的许多一般性任务,否则可能需要其自己的专用应用程序。数据库视图可以通过简单的鼠标点击显示或隐藏,如下面的食谱所示。您有自由选择您喜欢的数据库服务器——它可以是运行在您本地系统上的服务器,也可以是运行在云上并通过 IP 地址和用户名密码保护的服务器。

自定义视图

在软件工程师的生活中,有时似乎一切都不顺利,因此唯一出现在脑海中的想法就是改变一切。

PhpStorm 同样负责这个时间段,并提供视图的自定义——您可以自定义视图的显示方式。

如何做到这一点...

有两条路可以带您进入定制的世界:

  • 如下截图所示,位于单个视图右上角的设置按钮如何做到这一点...

  • 另一个非常简单且你最熟悉的选择是工具栏标题栏上的右键单击上下文菜单。

它是如何工作的...

通常,所有视图都可用一些上下文菜单选项,例如方向模式:浮动、停靠、固定和分割。视图可以处于以下状态:

  • 浮动模式:视图可以自由地位于屏幕上的任何位置

  • 停靠模式:视图在失去焦点时不会自动消失

  • 固定模式:视图保持在同一位置,直到被更改

  • 分割模式:您可以同时显示多个视图

将视图显示为标签页:此选项允许您根据各种标准过滤或分组您的任务,例如基于项目、基于当前正在编辑的以及基于范围。移动菜单允许您根据视图的当前方向将视图移动到顶部、右侧、左侧或底部。有选项可以拉伸或压缩窗口视图,以增加/减少视图窗口的大小。键盘快捷键是Ctrl + Shift + 向上 / Ctrl + Shift + 向下以增加/减少大小。

视图有单独的选项可用。保持清醒,探索以下列表中显示的各个视图窗口的定制选项:

  • 终端视图:根据您的需求,可以通过点击终端视图提供的+符号打开更多终端窗口。如果您觉得需要关闭活动终端窗口,可以非常容易地通过点击左侧的-符号来实现。此终端中可用的命令在底层操作系统上运行良好;例如,Linux 用户可以在此终端中输入 Ctrl + D 以退出终端,而 Windows 用户可以在此终端中输入他们喜欢的命令 dir

  • TODO 视图:此视图可用的特殊菜单选项在此列出:

    • 选择下一个标签页:这显示了 TODO 视图内的下一个可用视图。

    • 选择前一个标签页:此选项用于切换回前一个视图。

    • 显示标签页列表:这显示了所有视图。这提供了一个下拉菜单,可以从 TODO 视图内可用的视图列表中进行选择,如以下截图所示:

    如何工作...

  • 项目视图:如果您在 项目视图 窗口中,您应得的选项比一般选项更多。选项在此描述。保持关注并继续阅读。

    • 选择下一个视图:使用此选项可转到下一个视图标签。

    • 选择前一个视图;使用此选项可转到前一个视图标签。

    • 显示视图列表:使用此选项可从此窗口的可选视图列表中进行选择。

    • 显示成员:如果您在此处勾选,您将能够看到文件或代码中的成员函数和变量。

    • 自动滚动到源代码:此选项启用了一个非常有用的功能。如果您在此处选择一个文件,该文件将在编辑器中自动打开。

    • 从源代码自动滚动:这是一个与前面选项类似的功能。如果您在编辑器中选择一个文件,项目视图将自动显示在项目视图中选择的相同文件。

    • 按类型排序:虽然这个功能看似微不足道,但它可能在组织当前正在工作的项目中的文件和文件夹时非常有用。

    • 文件夹始终在顶部:您可以使用此功能让文件夹冒泡上升,文件将自动显示在文件夹列表下方。

    以下截图显示了项目视图的外观:

    如何工作...

  • 收藏夹视图: 这个视图部分提供了三个特殊功能:

    • 显示成员: 这个功能显示所选收藏夹中的成员列表

    • 从源自动滚动: 这与项目视图类似

    • 自动滚动到源: 这与项目视图类似

    收藏夹视图如下所示:

    如何工作...

  • 结构视图: 所有热情的程序员都应该养成使用这个功能的高强度习惯,因为这是一个更偏向于工程实践而不是 PHP 原则的功能。你应该始终将这个功能放在手边,因为当你感觉在辛苦的项目中迷失时,它绝对是你救星。所以检查你的安全带,准备开始这次信息之旅:

    • 按可见性排序: 使用此功能根据成员函数和变量的可见性对文件和文件夹进行排序。

    • 按字母顺序排序: 朋友们,请记住,这个功能只有在遵循规则书中的命名约定的情况下才会有用和有帮助。这个功能可以按字母顺序对成员函数和变量进行排序。这不是一个描述性的功能名称吗?

    • 显示包含的文件: 这个功能显示通过 PHP 代码程序化包含或要求的文件。

    • 显示字段: 这个功能显示类/文件中的字段。

    • 显示常量: 这个功能显示类/文件中的常量值。

    • 显示继承的: 这个功能显示具有继承关系的文件/类。

    • 显示工具栏: 这个功能以快速访问按钮的形式显示所讨论的功能,如下所示:如何工作...

  • 数据库视图: 大多数 PHP 程序员可能会问——为什么我需要在 PhpStorm 中拥有数据库视图?应该有一个类似于 SQLStorm 的 SQL 数据库工具。

    原因与可用性相关。在 PhpStorm 中添加 SQL 只是为了使一切都在一个屋檐下,并阻止程序员在 PhpStorm 和 SQLStorm 之间来回切换。此功能可用的右键单击上下文菜单选项包括:

    • 扁平化模式: 这个功能以一种相当扁平的方式显示数据库模式,而不是以树状结构显示。

    • 按类型分组表: 这个功能按类型对表进行分组。这有助于在数据库中搜索表,并增强了表的查看。

    • 按名称排序列: 这个功能按名称对所选数据库的列进行排序。

    数据库视图选项如下所示:

    如何工作...

访问任何项目文件

软件工程有时更多地是关于调整而不是创造。在有些情况下,开发者别无选择,只能切换到之前创建的某个项目,并希望使用某些功能(不侵犯版权,也不进行法律诉讼)。

准备工作

如果您需要在 PhpStorm 中访问任何项目文件,可以做出一些决定。当您同时处理多个项目时,访问项目更为重要。

如何操作...

如果您对文件中的一些内容有模糊的记忆,您可以对项目进行全局搜索以找到目标文件。这让你想起了寻找干草堆里针的老故事吗?

  1. 您可以打开一个文件夹,您的项目可能位于其中,如下面的截图所示。您可以通过导航到文件 | 打开来启动此过程。如何操作...

它是如何工作的…

即使文件夹不是 PhpStorm 项目,也不要担心。PhpStorm 足够智能,可以管理这一点。一旦打开,就可以在项目中搜索所需的文件/资源。PhpStorm 会将文件夹记住为项目,一旦索引,该文件夹的文件就可以像当前项目文件一样访问。

小贴士

您有一个热键可供使用:在需要的时候尝试Ctrl + Shift + N,并输入一些字母以获取匹配您输入字符串的文件名提示列表。

最大化视图和编辑器

虽然 IT 行业蓬勃发展,来自全球各地的候选人通过 IT 工作作为程序员谋生,但公司在提供基础设施和维护程序员适当的人体工程学方面仍然很吝啬。一个小型显示器就是这种人体工程学基础设施问题之一。PhpStorm 来拯救。

可以随意最大化视图或编辑器。视图可以通过右键单击上下文菜单中的调整大小选项或设置菜单中的选项来最大化(当处于停靠模式时)。为了更方便地操作,鼠标拖动也可以派上用场。只需单击并拖动所需的窗口即可调整大小。

良好的实践表明,编辑器应该是始终保持可见的唯一对象。其他视图应根据需要打开,并在任务完成后关闭。未停靠模式就是为了这个目的。视图根据需要出现,并在点击另一个视图或编辑器时消失。

PhpStorm 提供了一个出色的功能,通过提供全屏模式,让您可以专注于编码,只显示 PhpStorm 窗口。是的,您理解得正确。只有 PhpStorm 窗口可见,没有框架边框或操作系统项目可见。

如何操作...

要启用此功能,您需要执行以下步骤:

  1. 转到视图 | 进入全屏

  2. 要关闭全屏,请转到视图 | 退出全屏。这难道不难吗?确实如此。

PhpStorm 提供的另一个更好的功能是演示模式。在这个模式下,你将只看到字体放大的编辑器窗口。所有其他功能都将可用,但仅按需使用。这是 IDE 提供的最佳查看选项,适用于小型或单显示器。尽管背后的动机是帮助程序员向观众展示一些编码,但本节中所述的使用方法也很实用。要打开此功能,请转到 视图 | 进入演示模式,要关闭,请转到 视图 | 退出演示模式

返回上一个编辑器

强烈建议人类一次只执行一项任务。这是因为(大多数)人类不能多任务处理,因此如果他们尝试这样做,就会犯错误。对你来说也是一样。

准备工作

如果你必须处理一个需要你同时修改多个文件的项目,那么有很大可能性你会忘记你来自哪个编辑器,以及如果当前正在扫描的文件不是正确的副本,你应该去哪里。

如何操作...

在 PhpStorm 中,你可以通过记住(并且显然使用)快捷键来返回上一个编辑器、切换到下一个编辑器或从打开的编辑器列表中选择。为此,请执行以下步骤:

  1. 使用 Alt + 左键 切换到上一个编辑器。

  2. 如果你想切换到下一个编辑器,请使用 Alt + 右键

更多内容...

PhpStorm 提供了一个允许你移动到代码的任何部分或任何打开项目中的任何类的功能。这个功能使你能够随机访问当前打开项目中任何类的任何部分或任何打开文件的任何部分,如下面的截图所示:

更多内容…

并且,像往常一样,在 PhpStorm 的行为中涉及一些自定义。有一个过滤器符号。点击过滤器符号,相当隐晦地,允许你过滤搜索条件。你可以通过简单地取消选中不需要的文件或资源类型来告诉 PhpStorm 不要在某个文件或资源类型中查找。请参考前面的截图以获得清晰度。

为了启用随机访问,每个项目都需要添加到索引中。现在你可以为 PhpStorm 开发团队开发这个强大的索引系统表示赞赏。

返回上一个编辑位置

你不仅可以切换到当前打开的编辑器之间,还可以导航到最后一次修改的文件。

准备工作

这在那些你似乎在经理分配给你的工作负担中迷失,并且希望在非常短的时间内完成的情况中尤其有用。世界上所有的程序员都有许多相同的烦恼和担忧。

如何操作...

为了访问上一个编辑位置,请使用 Ctrl + Shift + E,并从弹出的列表中选择所需的文件。理解其工作原理相当简单。让我们看看以下截图,解释如何返回上一个编辑器:

如何操作...

将视图链接到编辑器

有时候,名称本身就一目了然。有时候,句子中会有提示。如果你得到了提示,那么你一定已经理解了 PhpStorm 提供的这个功能是为了显示代码在项目层次结构中的确切位置。如果你没有得到提示,别担心——既然你读了这段文字,你现在就明白了。请继续关注更多美味的食谱。

PhpStorm 提供了两种在视图和编辑器之间链接的方式。PhpStorm 可以在项目视图中显示的项目树层次结构中突出显示你当前正在编辑的文件的位置。

如何操作...

当你在项目视图中选择文件时,PhpStorm 也可以立即在编辑器中打开该文件。执行以下步骤:

  1. 要使用此功能,建议你阅读本章“自定义视图”食谱中提供的 自动滚动到源 的说明。

  2. 这种链接系统也适用于类成员(函数和变量)。PhpStorm 可以在编辑器和视图之间自动滚动(或链接),从而减轻你肩上的一些开发压力。真兄弟!

创建键绑定

对于那些觉得键绑定难以可视化的所有人,键绑定意味着键盘快捷键,它们是程序员生活中的变速器。当你全神贯注于必须在规定时间内完成的项目时,你可以在这个世界上打赌任何一种方式或手段,以影响你的工作效率。赌键盘快捷键吧。你将站在胜利的一方。

PhpStorm 再次指定了一些默认的 快捷键映射。朋友们,别担心!你可以非常容易地自定义键盘快捷键以适应你的口味。

如何操作...

  1. 使用键盘快捷键 Ctrl + Alt + S 或从 文件 菜单中选择。

  2. 前往 设置 对话框,在顶部提供的搜索框中输入 keymap,PhpStorm 将为你突出显示目标。

  3. 从以下截图所示的默认快捷键设置列表中选择,但迟做总比不做好。在跳转到更改快捷键之前,了解在 PhpStorm 中快捷键是如何工作的。PhpStorm 默认提供的快捷键映射不能直接编辑,因此为了自定义它们,你需要复制默认设置。听起来很复杂?PhpStorm 向导会为你创建副本。你的大脑会提出一个问题——我的设置在哪里保存?答案是——在基于 *nix 的系统下。如何操作...

它是如何工作的...

PhpStorm 使用目录 ~/.WebIde70/config/keymaps 来存储你创建的所有快捷键映射方案。仍然不自信?这里有一些行业技巧。

PhpStorm 会为您复制。它会要求您为此键映射方案命名。您指定的名称将被 PhpStorm 尊重。仔细观察后,您会发现 PhpStorm 会始终让您记住您的当前选择是基于 PhpStorm 提供的设置。在您完成选择并复制修改后,您所要做的就是按下应用按钮。恭喜!您刚刚创建了一个默认设置的副本,现在您可以按照自己的方式自定义 PhpStorm 的行为。

为了验证这一点,您可以转到~/.WebIde70/config/keymaps并查看 PhpStorm 刚刚为您创建了一个新的 XML 文件,其中包含您通过 PhpStorm GUI 创建的设置。每一个成功的客户端背后,都有一个同样强大的后端!

小贴士

如果您认为自己可以说 XML,您可以通过 GUI 创建一些设置,然后查看 XML 文件的内容以观察设置是如何保存的。您可以在稍后直接将项目添加到 XML 文件中。你这个淘气的黑客!控制你的笑容!

创建书签

书签非常实用。书签允许您在代码的某个位置放置一个标记,以便您可以通过快捷方式访问该代码。

PhpStorm 中的书签与书中读者通过放置一些纸张、翻页角或任何读者可以直接访问页面的方式所做的标记具有相同的意义。

如何操作...

PhpStorm 的书签创建起来非常简单。可以通过转到导航 | 书签来获得添加书签的选项。

这里解释了可用的三个选项:

  • 切换书签:此功能允许您在代码的某些指定行创建书签(如果不存在的话),以及从某些代码行删除书签。

  • 使用记忆法切换书签:此功能允许您使用记忆法切换书签,并附加了使用键盘快捷键访问该书签的能力。

    假设您选择的是字母数字0,如图所示,您将能够通过使用Ctrl + 0来访问该书签。

    如何操作...

显示书签:这是一个相当简单的功能。它只是让您查看您为正在工作的项目创建的所有书签。

小贴士

快速访问书签

为了能够通过记忆法快速访问书签功能,您所要做的所有艰苦工作就是记住键盘快捷键Ctrl + F11。其余的将由 PhpStorm 自动处理。

恢复已删除的资源

人非圣贤,孰能无过。从错误中干净利落地恢复是 PhpStorm 的强项。你犯错误是完全可以接受的。你可能正在想你的前任或你的汇报经理对你施加的恶行,让你加班(而他自己却在社交媒体上忙得不亦乐乎),你不小心删除了一些代码行。你不知道自己做了什么,带着沉重的心情,你下班回家了。第二天早上,当你准备开始工作时,你突然意识到你删除了一些代码行,但你记不清楚是哪些了!这难道就像是烧伤后的盐吗?需要药膏吗?深呼吸,感谢 PhpStorm 的开发团队,他们知道你是一个容易犯这类极端错误的凡人。

准备工作

你可以恢复从你的代码中删除的行。是的,你理解得没错。PhpStorm 中有一个历史功能,它在提供视觉辅助以查找对代码发生的更改方面是同类产品中最好的之一——无论是本地更改,即你是臭名昭著的代码更改的罪魁祸首,还是团队更改,即别人的代码破坏了你的代码。PhpStorm 帮助你指出错误或错误,并帮助你快速解决问题。

如何操作...

PhpStorm 会保存你写的每一行代码的快照。每次你保存时,它都会更新。所以,如果你想恢复一段代码,你需要通过使用编辑文件的时光作为锚点,深入到历史中。只要你切换到另一个窗口,它就会自动保存文档……这难道不是很酷吗。执行以下步骤:

  1. 本地历史选项在鼠标右键单击上下文菜单中可用。

  2. 一旦你点击或选择一个特定的时间,PhpStorm 就会显示历史文件与当前文件之间的差异,如下面的截图所示:如何操作...

  3. 你可以通过从右键单击上下文菜单中选择还原选项来恢复到(这个)特定的项目。完成!

  4. 你也可以通过双击大于号(>>)逐行合并代码。

它是如何工作的...

如果你从 PhpStorm 中删除了一个文件,无论是故意还是无意,你都可以使用相同的特性来恢复你的删除文件。你需要从项目视图中选择目标文件夹或目录,访问右键单击上下文菜单,并选择本地历史 | 显示历史选项。PhpStorm 不仅会非常容易地显示你删除的所有文件,而且还会以分层的方式显示,如下面的截图所示:

它是如何工作的...

你需要做的就是访问你想要从列表中恢复的文件的右键单击上下文菜单,并选择还原选择选项。请不要再吸烟和喝咖啡了。你的头痛问题解决了。

使用 PhpStorm 进行自定义

有时候,思考得足够多还不够。有时候,做得足够多还不够。关键是,尽管学到了很多,您仍然有一种感觉,认为还可以进行更多的自定义。PhpStorm 就在您的身边。

准备工作

您能做的最好的事情就是使用 PhpStorm 处理您所承担的任何 PHP 项目。但问题就在这里。通过 Web 服务器执行 PHP 是可以的,但当脚本需要在后台运行时怎么办?如果您的报告经理要求您进行一些套接字编程,您该怎么办?您需要一个 PHP 的命令行解释器。震惊的沉默?是时候打破这种沉默了。感谢 PhpStorm,并将其与 PhpStorm 集成命令行 PHP 解释器。

如何操作...

只需要一小串快捷键就可以调用命令行 PHP。实际上有两条路,也就是说,前方有一个分岔口。从分岔口,您将看到两条路——左侧是PhpStormish方式,右侧是操作系统 ish方式。值得注意的一点是,两种方式都能带您到达同一个目的地。在目的地,您将实现目标,即能够使用 PhpStorm 处理每个 PHP 任务。

您将首先通过 PhpStorm 的方式来进行。这比较简单,所以您应该先尝试它。这被称为 PhpStormish,因为 PhpStorm 让您感觉您正在使用 PhpStorm 本身来运行您辛苦编写的 PHP 代码。执行以下步骤:

  1. 为了以这种方式运行命令行 PHP,您需要转到设置 | PHP,如图下所示:如何操作...

  2. 这里有一个解释器下拉菜单。您需要添加一个解释器。您可以通过从 PHP 安装的bin文件夹中选择 PHP 解释器来实现。

  3. 一旦选择,您需要通过提供各种参数来对其进行自定义,例如名称和配置选项。在应用更改后,PhpStorm 中的 PHP 环境将由您底层操作系统的 PHP 环境提供支持。

  4. 这将使您能够使用默认的快捷键Ctrl + Shift + F10来测试和运行您的 PHP 脚本。

参见

注意

如果您安装了多个 PHP 版本,您可以添加更多解释器,并从中选择用于执行的解释器。

那做起来很简单,对吧?感觉很高兴?在这份快乐中,请不要忘记还有一条路,它在右边,而且又把我们带到了同一个目的地。PHP 脚本或代码可以在终端上运行。终端——这个词在你的脑海中响起铃声了吗?PhpStorm 为你提供了一个终端(模拟器),这样你就不必在心爱的 IDE(可能是 PhpStorm)和命令行终端之间来回切换。你可以再次使用这个功能来执行命令行 PHP 脚本。你只需要输入php your-php-file.php,如果你已经设置了 PHP 类路径,否则你需要添加一些额外的字母来使其变为/path/to/installed-php/php your-php-file.php

以下截图显示了如何在 PhpStorm 中通过命令行运行 PHP:

参见

添加包含路径

软件工程的一个原则是组件应该是可重用的,也就是说,软件的结构应该是模块化的。这是一个全球范围内接受的实践,但这给翻译(解释器或编译器)带来了额外的开销,因为它需要先找到模块才能将它们链接在一起。PHP 也不例外。

准备工作

每次运行脚本时,PHP 解释器都必须搜索所需的文件/文件夹/资源。然而,PhpStorm 可以通过允许你设置包含路径来减少搜索文件/文件夹所需的时间。包含路径是在你的操作系统下包含所有依赖项的文件和文件夹的基目录。

如何操作...

你有在 PhpStorm 中设置这个的自由。转到设置 | PHP | 包含路径。选择新的路径。点击应用。完成!看看下面的截图,它说明了这个观点:

如何操作...

小贴士

你应该始终确保在事先计划如何组织你的文件和文件夹,这样就不需要设置太多的包含路径。

如果在包含路径中提供了文件夹,它将有助于include()require()等自动完成。

从索引中排除不需要的目录

你尝试想象过为什么 PhpStorm 会知道你在项目目录结构中添加的所有文件的信息吗?PhpStorm 是如何通过添加图像、文本文件等来检测你对磁盘所做的更改,并设法在项目视图中显示它们的?是的,答案是索引。

准备工作

PhpStorm 对其遇到的所有内容进行索引。因此,它正确地记住了文件和文件夹。但这个系统中涉及一些开销。项目中的文件越多,创建的索引就越长。如果 PhpStorm 通过维护索引来减少搜索文件和文件夹的时间,那么当索引列表增加到非常大的规模时,它将如何管理在索引中进行搜索呢?

如何操作...

你可以通过以下步骤帮助 PhpStorm:

  1. 前往设置 | 目录

  2. 选择一个目录,你从这里需要记住的只有三个键盘快捷键:Alt + TAlt + E,和 Alt + R。请参考以下截图:

如何操作...

它是如何工作的…

Alt + T 将资源标记为测试资源,E 将其排除在索引之外,R 将其标记为内容根目录。对你来说,速度的提升将来自神奇的关键组合 Alt + E。对于那些你认为不足以被索引的目录,要足够无情地应用这个魔法。

注意

测试资源是一种资源类型,很可能是某些 PHP 脚本、某些目录或其他在测试过程中使用的文件类型。因此,一旦你知道它对测试目的有用,你就可以将资源标记为测试资源。

作为一款精心编写的软件,PhpStorm 使用索引维护了你项目中保存的所有文件的列表。因此,大量的文件意味着更长的索引,从而可能导致 PhpStorm 变慢。一个被排除的资源是你请求 PhpStorm 不要索引的某些文件或文件夹。

内容根目录是你正在工作的资源内容所在的文件夹或目录。你可能会很容易地问“它有什么作用?”答案相当简单:它为你维护一个干净的工作空间(生活中的一切都不必那么复杂)!

使用代码补全

使用 IDE 而不是标准编辑器的最佳例子是,IDE 理解你的代码,因此可以提供关于你可能正在编写或需要的代码的提示。

准备工作

标准编辑器最多只能提供基于各种关键字的基于基本文本着色。无论如何,不伤害编辑器的感情,PhpStorm 除了提供标准的代码补全系统外,还提供了额外的选项。

如何操作…

有智能类型补全功能,它不仅完成你的代码,还能找到并建议最适合你的代码的匹配项。通过“合适”的意思是,代码提示与当前上下文(调用对象)匹配。这在你需要坚持软件工程继承原则的情况下尤其有用。

在 PhpStorm 中,代码补全设置可在文件 | 设置 | 编辑器 | 代码补全中找到,如下截图所示:

如何操作...

它是如何工作的...

如果你有很多项目需要 PhpStorm 查找,例如,你创建的类的成员,你可以让 PhpStorm 按字典顺序为你提供提示。

要启用此功能,您需要选择与按字典顺序排序查找项相邻的复选框。以下截图显示了代码补全功能:

它是如何工作的...

便捷的代码补全!希望这对你来说是有意义的。

第二章:PHP 开发

在本章中,我们将涵盖以下主题:

  • 使用 Composer 创建 PHP 项目

  • 创建一个空项目

  • 重用现有项目

  • 创建一个新的 PHP 类

  • 创建一个新的 PHP 方法

  • 添加 getter/setter 方法

  • 创建代理方法

  • 使用控制结构包围代码

  • 查找匹配的大括号

  • 注释代码段和 PHPDoc

  • 创建工作集

  • 创建 TODO 任务

简介

现在你已经打开了前灯,你可以采取“无论发生什么”的态度,开始驾驶你最喜欢的汽车——PHP。现在你已经准备好了你心爱的工具——PhpStorm,就放手一搏吧。PhpStorm 将会负责消除你生活中的干扰,让你能够专注于编程。

你可以用 PHP 解决问题的任何方面来思考,PhpStorm 都会在那里帮助你。

你是否面临着一个即将解决的问题,一个让你感到棘手的问题,或者一个挑战你作为软件工程师存在感的问题?如果你坚持软件工程原则,PhpStorm 将会发挥你的能力,让你在解决当前问题时创造奇迹。PhpStorm 让你能够专注于设计业务逻辑,因为它会帮你分担记住细节的烦恼,比如确切的方法签名和参数列表。

想象一下,你的经理叫你去讨论一些必须尽快开发的新业务功能。你又陷入了困境。再次面临选择魔鬼还是深海的抉择。

PhpStorm 用户无需担心。他们有一个第三选择——乘坐直升机从当前场景中到达目的地。

你已经足够勇敢,从业务端收集了需求。现在你选择哪条路?决定你是想向右走还是向左走。如果你向右走,你将选择创建新项目的路线。如果你向左走,你将选择重用现有项目并对其进行修改的路线。

无论你走到哪里,无论你选择哪条路,你都必须达到同一个目的地。最后,你必须向你的经理汇报你为了实现目标所做的一切。你不仅必须快速决定,还必须迅速行动。

使用 Composer 创建 PHP 项目

欢迎那些走上正确道路的人!系好安全带,准备好在 PHP 中创建一个新的项目。

小贴士

创建一个新项目本身是一个非常成熟的决定,所以你应该始终成熟和战略性地做出决定。可能会有这样的情况,出于纯粹的激情,你选择了创建一个新项目,但几天后,你意识到你计划创建的大部分功能已经被开发出来了。你最终会做很多复制粘贴的工作。

准备工作

软件工程的原则总是教导学生,设计应该是高耦合和低内聚。这意味着应用程序应该使用其他程序,但不能依赖它们。PHP 中的 Composer 是一个帮助您采用这种方法的系统。Composer 是 PHP 的依赖管理器,它允许其他用 PHP 编写的包被包含在其他项目中。

PhpStorm 允许您创建遵循此原则的项目。要创建一个新的 Composer 项目,您需要在 文件 | 新建项目 菜单提供的下拉菜单中选择 Composer 项目 选项。接下来询问您的问题是要选择 composer.phar 的路径——从本地磁盘或从网站:www.getcomposer.org

如何操作...

不要因为完全的困惑而抓耳挠腮——更多的知识确实意味着更多的困惑,但这并不意味着你应该追求零知识以避免任何困惑!一个可执行的 composer.phar 文件引发了处理这些包的魔法。您可能正在想,Composer 内部究竟是什么让它成为当今的热门话题——每个人都似乎在谈论它。执行以下步骤:

  1. 前往 getcomposer.org/download/,您将看到以下命令:

    curl -sS https://getcomposer.org/installer | php
    
    
  2. 如果您在来到 PhpStorm 之前已经安装了 composer,您应该指定 /path/to/composer.phar,即 composer 已经安装的路径。

  3. 然后,您可以从左侧面板中的可用包列表中进行选择。在右侧,您可以查看所选包的相应描述。您可以选择要安装的包的版本,然后点击 确定

小贴士

下载示例代码

您可以从 www.packtpub.com 账户下载您购买的所有 Packt 书籍的示例代码文件。如果您在其他地方购买了这本书,您可以访问 www.packtpub.com/support 并注册,以便将文件直接通过电子邮件发送给您。

它是如何工作的...

命令实际上是两个命令的串联,它们获取安装脚本的内容并通过 PHP 命令行执行。如果您在网页浏览器中打开指定的链接,您将看到 Composer 背后的整个 PHP 代码。您能自由呼吸吗(当然,这里是一个双关语)?回到工作,命令的第二部分意图是通过 PHP 命令行执行 PHP 内容。

回到原始主题,您试图选择正确的 composer.phar 类型。看看下面的截图:

如何工作...

PhpStorm 会处理安装过程中剩余的 你选择的包 任务。

Composer 系统会生成一个名为composer.jsonjson文件,其中包含关于依赖项的详细信息。以下是一个从头开始创建的项目所对应的composer.json文件:

{
  "name": "2085020/api_pingdom",
  "description": "pingdom api for php",
  "require": {
    "guzzle/guzzle": "v2.7.2"
  },
  "authors": [
    {
      "name": "Emagister",
      "email": "jcruz@emagister.com"
    }
  ],
  "autoload": {
    "psr-0": {
      "Emagister":"src"
    }
  }

}

很明显,这个 json 文件向读者传达了大量的信息。"name":是下载的包的名称。"description":是下载的包的描述。如果你有很好的记忆力,你会记得在包选择窗口的右侧面板中有一个描述。这个描述正是相同的。"require":是此下载包所依赖的包的名称。json 文件指定项目名称作为键,相应的版本号作为值。"authors":是下载的包的作者。它包括作者的名字和电子邮件地址。"autoload":是编码标准,可以是 PSR-0、PSR-1、PSR-2、PSR-3、PSR-4,以及命名空间映射到实际目录。其层次结构如下:编码标准包含命名空间映射的值。命名空间映射意味着名称作为键,目录(相对于项目根目录)作为值。

PhpStorm 和 Composer 的组合效果显著。当你让 PhpStorm 下载并排列包时,它会自动为你安排项目的包含路径。现在不再会有关于缺失文件的警告或错误来阻碍你的工作。考虑以下截图:

如何工作...

假设你已经在项目中添加了一些包,现在你意识到你需要更多的包。不要担心,PhpStorm 会提供一个选项,让你以添加依赖项的形式添加更多包。这样做非常简单。在打开的项目中,你需要转到工具 | Composer | 添加依赖项。会出现一个熟悉的弹出窗口,要求你选择包名称并继续安装。其余的任务将像往常一样由 PhpStorm 处理。你将看到的将是下载的文件和文件夹,以及你特定项目的composer.json文件中的变化。以下是一个这样的composer.json文件的代码片段:

{
  "name": "redis/ranking",
"description": "Wrapping Redis's sorted set APIs for specializing ranking operations.",
  "keywords": ["redis", "ranking", "sort", "realtime"],
  "homepage": "https://github.com/matsubo/redis-ranking",
  "type": "library",
  "license": "PHP3",
  "require" : {
    "php": ">=5.3.0",
    "lib/curl": "0.3",
    "php-curl-class/php-curl-class": "1.0.1",
    "php-mod/curl": "1.0",
    "development/curl": "dev-master",
    "phpdocumentor/phpdocumentor": "2.0.0b7",
    "abhi/tangocard": "dev-master",
    "10up/wp_mock": "dev-master"
  },
  "authors": [
    {
      "name": "Yuki Matsukura",
      "email": "matsubokkuri@gmail.com"
    }
  ],

  "require": {
  },
  "require-dev": {
    "devster/ubench": "1.1.*-dev",
    "phpunit/phpunit": "3.*"
  },
  "autoload": {
    "psr-0": {"Matsubo": "src/"}
  }
}

符号具有通常的含义。外部依赖项已根据json标记添加到列表中,并由单个键 required 表示,其中值是具有键作为名称和相应版本作为值的依赖项的实际列表。

创建一个空项目

当你在困难时期找到一些支持时,你得到的感受可以与在口渴时找到冷饮的感觉相类比。这个陈述与当前情景的类比是,直到这个时间点,你无法找到要创建的确切项目类型,但现在你找到了一条出路。

准备工作

当你确信需要创建一个新项目并实现新的成就,以满足经理的业务需求时,你需要创建一个空的 PHP 项目。

如何操作...

创建一个新空项目是最容易的:

  1. 你需要为新项目指定一个名称。即使名称本身有拼写错误,也不要担心,因为 PhpStorm 不会将你指定的名称与字典进行核对。

  2. 项目名称应仅包含操作系统下目录名称应包含的有效字符。

工作原理...

创建一个空项目很容易理解。如果你已经有一些基本框架作为起点,你需要指定 /path/to/files/and/folders/。参见 集成框架,否则 PhpStorm 将为你设置默认路径(~/PhpstormProjects/<name-of-your-project>)。

重用现有项目

那些计划走右侧路线的人正确地选择了这样做。有时,重新发明轮子并不是一个明智的行为。

准备工作

如果你重用,你将能够避免在已经创建的东西上浪费时间资源。PhpStorm 允许你重用现有项目,并让你继续前进。要重用现有项目,你需要将项目放在磁盘上。

如何操作...

要打开现有项目,请执行以下步骤:

  1. 你需要转到 文件 | 打开。将会出现一个来自 PhpStorm 的弹出对话框。

  2. 你需要告诉 PhpStorm 保存项目的目录路径,PhpStorm 将为你自动打开项目。

    注意

    一旦某个目录在 PhpStorm 中作为项目打开,你将在下次能够区分它,因为 PhpStorm 会将它的标志放在这个目录旁边。

现在,你可以专注于收集你的技术需求。强烈建议你在实际编写代码之前提前做好规划,因为尽管完美的软件工程计划尚未存在,但你仍然可以保持乐观,创建一个足够好的计划,足够灵活,以便在需要时进行修改。

创建新的 PHP 类

当您来到厨房,您应该准备好在烹饪时弄脏双手。当您尝试烘焙数据结构时,您将不得不面对溅出的液体、成员变量的飞溅和汗水带来的湿润;它们可能太热而难以处理。您可能会在内侧造成灼热感(不受控制的酸度;有意为之)。您必须准备好可能添加的糖分不足(语法上的糖分),或者考虑错误的盐处理算法。各种烹饪问题都会困扰您,这可能会让您完全放弃烹饪并逃跑...害怕吗?也许吧...但您不会感到疲倦,您不会动摇,您也不会失败,亲爱的朋友们,罗马人和同胞们!

准备工作

一些基本概念...一些程序员总是谈论。实际上,所有人都应该。如果您一直想知道类究竟是什么,您首先需要理解数据类型。现在您可能已经开始怀念起学校时代,那时老师们用那些陌生的词汇困扰您。回来并尝试理解数据类型是什么。

数据类型是根据其类型(有些人喜欢称之为其属性)和操作(有些人更喜欢称之为其行为)对数据进行分类。那么类和数据类型之间有什么关系呢?答案是类是一个自定义数据类型。困惑吗?请不要困惑。如果您尝试创建一个类,您会做什么?您规划一系列成员变量…停止。

变量是如何定义的?这里有一个联系。因此,完整的陈述现在变为:您规划一系列成员变量、方法(函数,有些人喜欢这样称呼)来打包进一个类中。

一个类可以继承自另一个类,可以实现一个接口,或者被设计为可继承。您可以从集合{简单、抽象、继承、超类和子类}中的任何排列组合进行思考,您会发现大多数排列组合都是有效的。您如何解决问题?简单的常识会建议从问题的最容易部分开始解决。所以,这里是如何使用 PhpStorm 创建一个简单的 PHP 类。

如何做到这一点...

要准备创建一个新类,您可能已经创建了一个项目。在那个项目中,您可以通过选择目标文件夹并访问右键单击上下文菜单来创建一个新类。

PhpStorm 是一个好奇的机器。您刚要求它为您做点什么,它就开始向您提出一系列相关问题。在这里,当您要求 PhpStorm 为您创建一个新类时,它会问您以下问题:

  • 名称: 这一点相当直观,是一个必填字段。您需要告诉 PhpStorm 您想要创建的类的名称。在命名类时,您应该小心,因为这一点必须与您的项目工程计划保持一致。

  • 命名空间: 这是一个需要小心处理的选择。您需要指定命名空间,以便明确告诉解释器使用哪个版本的函数。这是一个可选但重要的字段——如果您不指定它,不会发生任何坏事,您也不会遭受任何疾病。

  • 文件名: 这是一个在使用时需要谨慎处理的选择。默认情况下,它假定与类的名称相同。如果您通过提供其他名称错误地处理此选项,您创建的任何产品都将完全归命运所有,没有任何工程原理能够轻松维护您的产品。

  • 目录: 在这里,您可以设置您希望类在磁盘上物理存在的位置。默认情况下,它假定您创建项目的位置——确切地说,是项目根目录。

  • 类型: 现在,这是您必须根据在选定此项目之前制定的工程计划来决定的事情。如果您有一个计划,根据该计划您将在稍后阶段决定功能,您可以将文件类型设置为接口;或者对于所有其他情况,您需要将类型选择为类。在这些条件下,您将添加盐到食谱中(有意为之)。特性是一种有“我也一样”哲学的东西。现在您可以安全地忽略它。

  • 文件扩展名: 这是一个不建议您不必要地更改的选项。所有 PHP 文件的核心只有一个扩展名——.php文件。PhpStorm 知道这一点。请允许它继续。

添加类选项可通过两个菜单项获得。其中一个已经讨论过,对于另一个,请执行以下步骤:

  1. 前往 文件 | 新建如何操作...

它是如何工作的...

一个简单的示例类将如下代码片段所示:

<?php
class Review {

}

在 PhpStorm 中创建接口也不困难。告诉 PhpStorm 创建接口时,输出将与类类似,只是将关键字“class”替换为关键字“interface”。它看起来如下所示:

<?php

interface Readable {

注意

如果您想区分类和接口,那么您只需要在 PHP 方面的常识即可。Class关键字用于类,而interface用于在 PHP 中创建接口。

创建新的 PHP 方法

如果代表现实世界实体的类是名词,那么没有动词——要执行的动作——它们就不存在。为了能够最大限度地提高您为经理创造的技术利润,您必须准备好使用函数来处理您用例中存在的所有动词。

准备工作

假设你手头有一个披萨烹饪任务。食谱将包括一个(最基本)披萨面包(名词),奶酪(名词),一些盐(名词)。如果你思考你的问题,你会意识到你需要将奶酪涂抹在披萨面包上,并按口味添加盐。如果你从技术角度看待这个场景,你可能会决定需要一个PizzaDish类,其中包含applyCheese(pizzaBread)addSalt(cheese)等函数。

如何操作...

在 PhpStorm 中创建一个方法很简单。假设你有一个PizzaDish类。你的披萨菜肴是一个Dish,所以你的PizzaDish会扩展Dish。你的类如下代码片段所示:

<?php
class Dish {
/**
* @param string $dishName The name of the dish
*/
protected function addSalt(){}
}

你的PizzaDish类可以如下代码片段所示:

<?php
class PizzaDish extends Dish{
  private $dishName;
  function addSalt($dishName){
    $this->dishName = $dishName;
    parent::addSalt($this->dishName);
  }
}

在 PhpStorm 中编码可以通过使用代码提示或代码补全来简化。你只需输入几个字符作为提示,PhpStorm 就会准备好建议下一步可能的内容。你输入fun并按Ctrl + Space,就会出现关于你的函数可以是什么的多个提示。如果你想对你的披萨制作食谱进行更多操作,比如添加一些配料,如彩椒或蘑菇,你可以有一个通用函数,add($ingredient, $dishname)。你可以在你的PizzaDish类中这样做。你可以使用代码补全来设置访问修饰符。你必须手动处理其他操作。

要将方法addSalt()转换为add(),你需要重命名addSalt方法。这可以通过 PhpStorm 的重构选项完成。

要重构一个项目(这里指addSalt方法),可以通过右键点击上下文菜单进行操作 | 重构 | 重命名重构 | 更改签名

如以下截图所示,重命名子菜单只会更改方法的名称:

如何操作...

更改签名选项是一个更详细的重构功能,你可以更改方法的全签名,如下面的截图所示:

如何操作...

因此,你的新添加函数如下代码片段所示:

<?php
require_once 'Dish.php';

class PizzaDish extends Dish{
  private $dishName;

  function __construct($dishName){
    $this->dishName = $dishName;
  }

  function add($ingredientName){
    parent::add($this->dishName, $ingredientName);
  }
}

在父Dish类中也发生了类似的变化,其中addSalt方法已被重命名为add,如下面的代码所示:

<?php
class Dish {
  /**
  * @param string $dishName  The name of the dish
  */
  protected function add($dishName, $ingredient){
  }
}

你可以通过执行以下截图中的代码来使用PizzaDish类及其方法:

$pizzaDish = new PizzaDish('New Pizza');
$pizzaDish->add('salt');
$pizzaDish->add('cheese');
$pizzaDish->add('capsicum');

它是如何工作的...

代码生态系统的运作相当简单。你通常实例化了PizzaDish类。你调用了add函数。但是,当你实际调用add函数时,究竟发生了什么?add函数调用了其父类中定义的add函数(记得在PizzaDish的开始处添加了extends)使用一个特殊的词——parent。所以,你以为你调用的是PizzaDishadd方法来做你的工作,但实际上是Dish做了你的工作!不,不,这并不是欺骗。这是继承,正如软件工程原则所解释的。

小贴士

键盘快捷键是Ctrl + F6Shift + F6,分别用于更改签名和重命名。

添加 getter/setter 方法

在 PhpStorm 中添加gettersetter方法同样简单。你所需要做的只是拥有一个类的成员变量。在PizzaDish示例中,它是dishName

准备工作

要为dishName创建 getter 和 setter,PhpStorm 提供了这样的功能。如果你需要,可以通过右键单击目标变量的上下文菜单,点击生成并从弹出菜单中选择gettersetter。PhpStorm 将为所选成员创建所需的 getter 和 setter。

你的PizzaDish类现在将看起来像以下这段代码:

<?php
require_once 'Dish.php';

class PizzaDish extends Dish{
  private $dishName;

  /**
  * @param mixed $dishName
  */
  public function setDishName($dishName)
  {
    $this->dishName = $dishName;
  }

  /**
    * @return mixed
  */
  public function getDishName()
  {
    return $this->dishName;
  }
  function add($ingredientName){
    $this->setDishName($ingredientName);
    parent::add($this->dishName);
  }
}

如何操作...

添加盐、奶酪和红椒的过程仍然是相同的。

你必须将以下几行代码发送到你的 PHP 引擎,以便创建一个新的披萨盘并添加一些配料:

$pizzaDish = new PizzaDish('New Pizza');
$pizzaDish->add('salt');
$pizzaDish->add('cheese');
$pizzaDish->add('capsicum');

它是如何工作的...

之前,当你需要访问$dishName时,你是直接访问的。这引发了许多不良的工程实践,例如暴露成员变量的表示。实际上,这个列表是无穷无尽的。你所需要做的只是确保你必须使用 getter 和 setter 来成为一名优秀的软件工程师。所以,在你提供的代码中,你只需要调用getter方法(例如getDishName)和setter方法(例如setDishName)。

你是否仍然感到不舒服?要有耐心。欢迎来到真正的软件工程世界。

创建委托方法

委托是软件工程中的一个重要设计模式。它增强了代码的可重用性。

准备工作

在 PHP 中,可以按照委托原则创建委托方法。在调用委托函数时,你不需要事先知道实际函数的名称——PHP 引擎可以为你找到它。

如何操作...

PHP 提供了两个工厂方法用于此目的。然而,你可以使用面向对象编程的原则创建自己的委托方法。

PHP 提供的工厂方法是call_user_func()call_user_func_array()。虽然这两个方法的用法超出了本文的范围,但委托方法的创建和使用可以通过以下代码中所示的烹饪PizzaDish的相同场景来更好地解释:

<?php
require_once 'Dish.php';

class PizzaDish{
  private $dishName;

  /**
    * @param mixed $dishName
  */
  public function setDishName($dishName)
  {
    $this->dishName = $dishName;
  }

  /**
  * @return mixed
  */
  public function getDishName()
  {
    return $this->dishName;
  }

  private $instance;

  /**
    * @return mixed
  */
  public function getInstance()
  {
    return $this->instance;
  }

  /**
    * @param mixed $instance
  */
  public function setInstance($instance)
  {
    $this->instance = new $instance;
  }

  function __construct($dishName, $instanceName){
    $this->setInstance($instanceName);
    $this->setDishName($dishName);
  }

  function add($ingredientName){
    $this->getInstance()->add($ingredientName);
  }
}

委托方法的用法几乎相同,但并不完全相同:

$pizzaDish = new PizzaDish('New Pizza', 'Dish');
$pizzaDish->add('salt');
$pizzaDish->add('cheese');
$pizzaDish->add('capsicum');

现在 Dish 类看起来如下:

<?php
class Dish {
  /**
    * @param string $ingredient The name of the ingredient to be added
  */
  public function add($ingredient){
    echo "\nYou have added: ", $ingredient;
  }
}

它是如何工作的...

惊讶吗?这里发生的事情是,当你调用 PizzaDish 类并传递 Dish 类的名称到构造函数中,$instance 的值是 Dish 类的一个新创建的对象。其余的,就像它进行的那样,是通过类对象进行的常规方法调用。现在你可以深呼吸了,因为你已经将 PizzaDish 中的 add 函数委托给 Dishadd 函数。看起来 PizzaDish 类正在执行任务,但实际上是由 Dish 类完成的。

使用控制结构包围代码

无论你想到什么算法,无论你使用什么工具来设计功能需求,无论你前往哪个星球,使用什么硬件作为你的开发平台,都有一个无处不在、无所不在的事实:循环将伴随你到任何地方。控制结构是任何你想到的代码的构建块。你不信?你的 PizzaDish 用例本身就能证明这一点。

准备工作

你首先需要一个计算机来勤奋地计算、做决策和解决复杂问题。计算机只解决一个问题就停止了吗?不。它被编程为继续执行所有可能的指令次数。程序是如何实现这种勤奋的呢?你说对了。请说得再大声一点。是的,控制循环。即使这个解释可能对你们这些高手来说显得微不足道,但事实是,没有控制结构,你无法继续编写代码。

PhpStorm 允许你编写代码。它让你专注于实际的业务逻辑。你可以编写你认为将是原子部分的代码行。当你确信逻辑正确时,你可以使用 PhpStorm 的 Surround 功能将这段代码包围在你的期望控制结构中。

如何做...

如果你希望向你的 PizzaDish 添加配料,你可以使用循环。有多种方式来表达一个单一语句:

  • 使用 foreachPizzaDish 类的调用方式如下:

    $pizzaDish = new PizzaDish('New Pizza', 'Dish');
    $ingredients = array('salt','cheese','capsicum');
    foreach ($ingredients as $ingredient) {
    $pizzaDish->add($ingredient);
    }
    

    你必须在这行代码上保持光标位置,编写 $pizzaDish->add($ingredient)

    通过访问 代码 | Surround with 来调用 Surround,并选择 foreach 选项为你解决了问题。然而,你必须指定循环结构内部的变量。你也可以使用键盘快捷键 Ctrl + Alt + T

  • 你可以对 for 循环执行类似操作。这个更改将允许你调用你的代码。看看下面的代码片段:

    $pizzaDish = new PizzaDish('New Pizza', 'Dish');
    $ingredients = array('salt','cheese','capsicum');
    for ($count = 0; $count < count($ingredients); $count++) {
      $pizzaDish->add($ingredients[$count]);
    }
    
  • 通过使用 while 控制结构包围代码,执行类似的操作。你的 PizzaDish 通过以下代码片段被调用:

    $pizzaDish = new PizzaDish('New Pizza', 'Dish');
    $ingredients = array('salt', 'cheese', 'capsicum');
    $ingredientCount = 0;
    while ($ingredientCount < count($ingredients)) {
      $pizzaDish->add($ingredients[$ingredientCount]);
    $ingredientCount++;
    }
    

    仔细观察会发现,while 循环的行为与 for 循环的行为完全相同。那么为什么有两个功能来实现相同的功能呢?人类的大脑喜欢有更多的选择。一段(伪)代码能更好地解释这一点:

    while($moreChoicesAvailable){
      $humanMind = array(
        'feeling' => 'happy',
        'status' => 'comfortable'
      );
    }
    

它是如何工作的...

这里解释的两个控制结构有很多共同之处。简而言之,它们可以被称作入口控制结构,因为它们遵循先决定后执行的原则。它们并不是为了让你后悔自己的行为(有意为之)。有一个枪手控制结构,它靠枪活着,也因枪而死,即do-while循环。如果你在使用它时没有给予适当的注意,它可能会让你后悔自己的决定。在同样的术语下,它是一个退出控制结构,并且至少会执行一次任务。虽然在某些情况下这可能是必需的,但你被建议避免使用do-while。看看下面的截图:

$pizzaDish = new PizzaDish('New Pizza', 'Dish');
$ingredients = array('salt','cheese','capsicum'
);

$ingredientCount = 0;
do {
  $pizzaDish->add($ingredients[$ingredientCount]);
  $ingredientCount++;
} while ($ingredientCount < count($ingredients));

因此,本质上,语句$pizzaDish->add($ingredients[$ingredientCount])至少执行一次,将$ingredientCount的值增加一,然后检查该值是否在限制范围内。要使用do-while,你需要将光标放在目标语句上,并在代码 | 用...包围选择对话框中选择出现的do-while选项。

小贴士

为了让你的应用程序程序足够负责,你需要实现由try-catch块表示的异常处理。在这个菜谱中,将展示一个简单的用例来演示异常处理的用法。你试图准备你的PizzaDish。你计划像往常一样放盐和奶酪,并作为配料放彩椒以使其变得令人惊叹。然而,在烹饪过程中,你发现冰箱里没有彩椒!但你饿得足够厉害,不会让任何东西阻碍你和你PizzaDish之间的距离。在这种情况下,你将添加番茄。那么,这段代码中的责任在哪里?那就是在代码准备阶段处理一个异常情况时,配料缺失,但代码承担了责任,通过添加番茄代替彩椒来处理这个异常情况。

你的PizzaDish继续以下方式烹饪:

$pizzaDish = new PizzaDish('New Pizza', 'Dish');
$ingredients = array( 'salt', 'cheese', '' );
$ingredientCount = 0;
try {
  while ($ingredientCount < count($ingredients)) {
    if ($ingredients[$ingredientCount] == '') {
      throw new Exception("\nYou have run out of capsicum.");
    } else {
      $pizzaDish->add($ingredients[$ingredientCount]);
      echo "\nWaiting for capsicum topping...";
    }
    $ingredientCount++;
  }
} catch (Exception $e) {
  echo $e->getMessage();
  $pizzaDish->add('tomato');
}

以下截图展示了如何查看 which-control-to-surround 的外观。值得注意的是,你应该知道你将要使用哪种控制结构。

如何工作...

查找匹配的大括号

如果你拥抱大括号,你永远不会感到尴尬。

一些 PhpStorm 食谱作者

准备就绪

大括号是编程中的重要元素。它们不仅为程序员定义了边界,也为解释器定义了边界。你们两个都知道结构或变量的范围从哪里到哪里。PHP 解释器只需要为每个开括号有一个闭括号来继续执行,而不论代码是如何编写的。但是,PHP 解释器并不强大到可以为你编写代码——你必须自己来做。

如何做到这一点...

如果你提供一小段少于 100 行长的代码,你设法阅读和维护代码。如果行数超过 100,代码格式化就会帮助你。

PhpStorm 允许你通过简单的鼠标点击或单个键盘快捷键格式化所有或部分选定的行。要格式化代码,你需要选择代码 | 重新格式化代码,你的代码将像魔法一样被格式化。

这个快捷键是Ctrl + Alt + L

它是如何工作的...

在 PhpStorm 格式化代码后,你的生活变得更轻松了。你可以通过将光标放在括号上非常容易地找到匹配的括号。配对的括号会自动高亮。这个高亮功能也可以自定义。你需要转到文件 | 设置 | 编辑器 | 光标移动时高亮显示,勾选或取消勾选高亮匹配括号复选框来开启或关闭高亮匹配括号。你可以更改括号颜色、括号背景颜色等。你可以使括号看起来加粗或斜体。为了自定义这种行为,你需要设置一个新的方案。首先,你需要转到文件 | 设置 | 编辑器 | 颜色与字体 | 语言默认值 | 括号,选择一个默认主题,然后进行另存为以创建一个副本,如图所示:

如何工作...

注意

你刚刚保存的颜色方案被保存为扩展名为.icls的 XML 文档,位于~/.WebIdeXX/config/colors目录下。该文档的名称与你在复制颜色方案时提供的名称相同。

还有更多...

让我们看看如何格式化一个长字符串。

换行字符串

当你编写了一些非常长的字符串或一些非常长的语句时,代码格式化的另一个重要方面变得尤为重要。你可能试图阅读这些长行时会遇到麻烦。即使你设法阅读了,你也可能对那些长、难以处理的长行的开始和结束感到困惑。

PhpStorm 允许你根据固定宽度包裹长行和语句。你可以通过访问文件 | 设置 | 编辑器 | 虚拟空间面板,让 PhpStorm 为你记住一些限制。

你可以通过选择编辑器中使用软换行选项旁边的复选框,在编辑器中包裹长行。长行不仅会在编辑器中折磨你。当你使用 PhpStorm 终端执行命令行 PHP 时,有时也会创建使用折磨。如果你勾选在控制台中使用软换行选项,你可以一劳永逸地避免这个问题。PhpStorm 为你提供了设置控制台中换行缩进级别的选项。如果你选择此复选框,包裹的长行将继续到下一行,但带有指定的空格数。现在,你不能抱怨你不确定哪一行是你的包裹行,哪一行是你的原始行!

注释代码段和 PHPDoc

PHPDoc是 PHP 提供的一个功能,旨在记录你非常努力构建的复杂代码。对于那些在某个时刻照顾过他人代码的人来说,代码记录和良好记录的代码的重要性无需解释。对于所有人,以及那些知道但渴望知识的人,这里有一些可能解释为什么你应该始终记录你的代码——无论是什么和如何。敬请期待一些有趣的用例。

准备工作

你计划制作PizzaDish。你是如何进行的?你创建了一个名为Dish的实体,并在其中设计了一些函数来帮助你添加一些配料,并创建了一般情况Dish的特殊情况。你将这个特殊情况命名为PizzaDish。为了制作你的披萨,你调用了PizzaDish并享受了你最喜欢的披萨。一切都很顺利。但是,有多少次你没有做其他事情?你能只吃披萨过一生吗?你不认为你还有其他任务要完成吗?这里有一个类比。有多少次你需要除了你编写的代码之外的其他东西?你能只通过使用你自己的类或代码成为一个优秀的程序员吗?你会为每个你执行的任务创建算法吗?

简而言之,你相信重新发明轮子吗?

普通人可能会回答不。对他们来说,你是如何使用其他程序员编写的类的?你是如何发现Engine::start('car')函数会打开点火开关的?这就是文档的作用。它是你能够发现Engine类中的启动方法旨在打开发动机点火开关的媒介。

编写干净的代码是文档化的第一个关键。你应该始终考虑那些能解释很多内容的名称。你应该始终考虑描述性的名称。如果你认为你的名称快要用完了,你可以利用 PHP 命名空间。

为了开始思考如何编写干净的代码,你被要求仔细阅读这本书。为了开始编写干净的代码,你被要求开始编写代码。

如何做...

如果你足够细心并且记忆力好,你早就已经阅读了DishPizzaDish类。看着变量是如何定义的,方法是如何声明的,你是否觉得需要其他文档?他们说得好,他们说得对:好的代码本身就是好的文档。但是,如果你在代码中无法想到描述性的名称,那么 PHPDoc 就是你的救星。

你有三种方法可以向你的代码中添加注释:

  • 单行注释

  • 多行或块注释

  • 文档注释

为了学习,你必须执行。为了执行,你必须开始。那么,让我们开始吧。为了使PizzaDish类本身更清晰,请添加注释到该类上。

PHP 代码中单行注释是最简单和最易写的一种注释形式。单行注释以//开头,PHP 引擎将单行中跟随的内容视为单行注释。在PizzaDish类中,旁边已经添加了成分列表(PHP 数组)的单行注释,如下所示:

// This is the list of ingredients that you plan to add

为了在 PhpStorm 中写单行注释,你需要注意注释的位置。

小贴士

你可以写注释而不需要以//开头。当你完成你的句子时,你可以使用快捷键Ctrl + /,PhpStorm 会愉快地将语句转换为单行注释。

你的生活能被限制为只写一行注释吗?如果你想要有多个单行注释呢?需要多行或块注释。

你需要做的只是确定宝贵的代码范围,并在代码的开始处添加/*,在结尾处添加*/。在这个世界上,有些人对“宝贵”的概念一无所知。所有优秀的软件工程师都会忽略这样的人,继续前进。在讨论的PizzaDish类中,你可以看到最后几行被注释掉了。这是一个块注释。在当前情况下,你的味蕾是商业端,人们!

文档注释以/**开头,以*/结尾。这看起来不像块注释吗?更仔细的检查会告诉你它们之间的区别。

虽然块注释只需要一个开始符号和一个结束符号,但文档注释需要在每一行的开始处有一个*符号。虽然 PHP 引擎会跳过块(和多行)注释中的内容,但在生成实际的漂亮注释时,PHP 引擎(实际上是文档引擎)会“窥视”文档行。你在哪里能看到文档?亲爱的,当你按Ctrl + Q在任何方法声明上时,你看到了什么?是的,它是一个与文档引擎生成的相同的文档。魔法?PhpStorm 的魔法。

爆炸!太长了?没看?下面是一步一步的解释:

/**
  * Class PizzaDish
  *
  * Bake a new type of <strong>Dish</strong>.
  * This dish has the following features:
  * <ul>
  * <li>It eases the appetite</li>
  * <li>It makes the taste buds happy</li>
  * <li>It confirms to the software engineering practises</li>
  * <li>It teaches engineers various aspects of PHP programming</li>
  * </ul>
*/

工作原理...

这可能是你第一次查看文档注释。你会惊讶地发现,你在这里写的 HTML 标签实际上是由 PHP 文档引擎处理的。文档注释的输出出现在你将光标放在目标成员上并转到视图 | 快速文档时:

工作原理...

一图胜千言。你可以轻松地看到 HTML 标签是如何被处理以给文档提供正确格式的。

同样,你也可以给你的方法添加文档(同一个类和同一个方法,但这次是setDishName,并添加了文档)。文档行如下所示:

/**
  * <strong>Setter</strong> method for giving a name to your Pizza<br/><br/>
  * In order to set values for the members variables, it is <em>advised</em> to use setter methods.
  * @param string $dishName The name of the dish you want to create.
  */

你刚刚使用了 HTML strong 标签来强调setDishName方法的类型。你还能够强调软件工程原则建议使用 setter 方法。这个方法的注释采用以下形式:

如何工作...

小贴士

为了使用键盘快捷键Ctrl + Q,你不必一定将光标放在方法名下。这也适用于文档注释区域。PhpStorm 很智能,所以它理解这一点,并显示相同的文档。

PhpStorm 从不让你失望。在 PhpStorm 中有一个功能,你可以自定义你的文档注释的外观。为此,你需要转到文件 | 设置 | 代码样式 | PHP | PHPDoc,如下面的截图所示。选项相当详细。

如何工作...

创建作业集

你可能多次感觉到不同的 PHP 项目有不同的优先级。你做得对。例如,一个网站开发项目可能需要一个运行的 Web 服务器配置,可能不需要命令行 PHP。

准备就绪

另一方面,一个简单的 PHP 项目可能需要命令行 PHP,而不需要 Web 服务器,目录列表可能仅限于层次结构中的某些文件夹。这里的要点是,不同的项目有不同的依赖和设置。拥有一个作业集使得 PhpStorm 能够为当前打开的项目做出适当的反应。

如何做到这一点...

如果你仔细监控设置面板,你会注意到有两个主要部分。一个是项目设置部分,在这里你可以根据你的项目进行设置。这非常有帮助。PhpStorm 为每个项目构建一个索引。如果你为你的项目创建一个合适的作业集,这将帮助 PhpStorm 构建一个更精确的索引,项目处理将更快。一些重要的设置包括:

  • PHP 特定设置:为你要创建的应用程序执行设置是非常方便的。你不必担心如何执行和测试你的应用程序。你只需要从 PhpStorm 在你面前提供的选项列表中选择即可。

  • 解释器:你可能需要在你的 Web 托管服务上实现一些离线任务,这可能包括更新、检查、日志清理等任务。你可能需要为这些文件配置命令行 PHP,以便你可以通过直接键盘快捷键访问它们。

  • Web 服务器:大多数情况下,你需要有一个 Web 服务器来运行你的 PHP Web 应用程序代码。为此,你可以在 PhpStorm 中指定 Web 服务器的设置。

  • 调试器:对于 Web 开发者来说,没有调试器的生活就像医生没有听诊器的生活。当你不知道内部发生了什么时,你怎么能找出真正发生的事情呢?你肯定需要一个调试器。

  • 目录:PhpStorm 为项目中的文件和文件夹建立索引。较长的索引列表意味着更多的内存消耗。排除不需要的 目录 从索引中,PhpStorm 会感激您。

  • 检查:PhpStorm 作为您所写代码的检查员。默认情况下,有一些检查是开启的,并且很可能您并不需要在任何时候都需要所有这些检查。

  • 版本控制:如果您在一个团队中工作,拥有一个版本控制系统是当务之急。您可以设置版本控制系统的详细信息,例如 URL、用户名、密码以及所有在下载(检出)或上传(提交)团队正在工作的项目时使您生活更轻松的必要细节。

另一个是 IDE 特定的设置部分。这为您提供了对所有在 PhpStorm 下的项目都普遍适用的配置的控制。描述超出了本主题的范围。

创建 TODO 任务

假设这是一天结束的时候,您必须 匆忙回家(没有开玩笑),您脑海中充满了绝妙的主意,您非常确信您将无法重新生成这些想法。在这些情况下,您可以请求 TODO 来帮助您。

准备工作

当在 PHP 代码中添加 TODO 标签时,它会在 TODO 视图中变得可见。您还可以参考本章的 TODO 部分,以进行复习。

考虑到相同的 DishPizzaDish 场景,假设您想到了一个检查菜肴是否煮熟的系统,您可以在那里放置一个标志。这个标志会不断提醒您这一点。

如何操作...

要执行 TODO,您只需写下 TODO,然后是提醒文本,并按 Ctrl + /(即注释代码)。根据您已经学到的知识,您现在可以记录您的 Dish 类。可能看起来像以下代码片段:

class Dish {
  /**
  * Add some ingredients to your dish. <br/>
  * You can do that by specifying the name of the ingredient.
  *
  * @param string $ingredientName The name of the ingredient to be added
  */
  public function add($ingredient){
    echo "\nYou have added: ", $ingredient;
  }

//    TODO Add some method to check if the pizza is cooked
}

您成功地保持了功能完整;您只是为类和成员方法添加了文档注释。其他一切都是常规操作;唯一的外来物品就是 TODO。所以,如您所见,简单地添加了一个 TODO。人们可能会争论 TODO 的用法。他们说的对,也说的不对。他们说的对的情况是小型项目,其中代码不多,简单的注释可见且容易记住。在其他所有(和现实世界)情况下,他们完全错误,在这些情况下,有无数行代码,您实际上可能会在试图找出与某个建议相关的注释时遇到噩梦。PhpStorm 能够从您的项目中提取所有 TODO,并在 TODO 视图中准确显示。

它是如何工作的...

除了提醒您未来要完成的任务外,还可以有一些 FIXME 标签。正如其名所示,FIXME 标签可以用来表示一些产生错误或容易产生错误的特性。您只需使用 FIXME 关键字,然后是描述,接着使用 Ctrl + /(注释)即可。PhpStorm 将开始在 TODO 部分显示它,如下面的代码所示:

public function add($ingredient){
  echo "\nYou have added: ", $ingredient;
  //  FIXME Check for a valid ingredient name
}

fixme(或 FIXME)标签将开始指示存在一些必须修复的问题。

然而,TODO 还没有结束。如果您的开发团队中有许多程序员,您可以为个别队友添加标志。如何?PhpStorm 为您提供了过滤器。这可以在 文件 | 设置 | TODO 中找到。

您需要添加一个新的模式和新的过滤器,以便在 TODO 视图中的过滤器部分使其可用。添加后,您将能够为特定的程序员设置标志。具有此新标志的代码看起来像以下片段:

public function add($ingredient){
  echo "\nYou have added: ", $ingredient;
  //  FIXME Check for a valid ingredient name
}

//  TODO Add some method to check if the pizza is cooked
//  TODO for ALice Please add the appropriate usecase for the checking functionality

默认情况下,过滤器和模式不区分大小写,因为程序员的日常生活中已经有很多问题需要处理。请记住这一点!

你能完成 TODO 吗?

如何工作...

第三章。重构和构建

在本章中,我们将介绍以下食谱:

  • 重命名元素

  • 复制元素

  • 移动元素

  • 移动一个方法

  • 移动一个变量

  • 删除元素

  • 在项目中搜索代码

  • 比较文件

  • 使用比较来恢复元素

  • 设置运行配置

  • 运行你的代码

简介

奶奶的建议:坚持软件工程。

软件工程建议:强调代码的可重用性。任何根据软件工程范式构建的代码库都将可重用。也就是说,你一旦编写了代码,就可以永远使用它。他们常说“一次编写,永远使用”。

回顾披萨烘焙用例,你会观察到为了烹饪任何菜肴,你只需使用add函数,因为你坚持了上述范式。假设你将要烹饪 50 种不同的菜肴。每种菜肴本身都不同,但每种都需要add方法。如果你将这转化为技术,你将在大多数情况下继承Dish类。那就是你的PizzaDishDish类的所有方法都在PizzaDish等所有类中重用。

如果你想要更改业务逻辑,你可以愉快地舒适地更改方法体内的逻辑,并且这些更改将在继承(或使用)此类的所有类中反映出来。

到目前为止,一切顺利...但是,如果你要更改基类内部方法的签名,你会怎么做?是的,这可能在开发初期,当计划略有变化,从而导致用例变化时出现。

重命名元素

正如俗话所说,变化是不可避免的;你必须为变化做好准备,无论时间表如何。工程师在重命名时可能会犯错误——打字错误、忘记在哪里更改等等。别担心,至少你可以放心,因为你有 PhpStorm。PhpStorm 所做的是提供一个重构系统,在这个系统中,你可以让你的更改在整个项目中渗透,一步到位:重构步骤。如果你选择重构,你将拥有进行多项重构任务的自由。

因此,addIngredient方法可以在代码的某个地方轻松地写成addingredienttoolTip可以写成tootLip等等。在你的代码中可能有五个地方使用了addSalt方法;但是,当你更改add的方法签名时,不知何故你忘记了,只在你代码库中的四个地方进行了更改。这样的小错误可以安全地称为愚蠢的错误,但可能会造成比你想象的更大的损害。它们消耗了最宝贵的资源——时间。你最终会意识到这只是一个打字错误或失误,但只是意识到你已经错过了截止日期。

通过重构,你可以安全地重命名方法签名,并告诉 PhpStorm 通过查找并跨所有出现进行相同的更改来渗透这个更改。

重构适用于代码的所有元素:类名、方法名、方法签名、变量名等等。PhpStorm 将它们视为一样!正义的 PhpStorm!

在 PHP 项目中,目录与 Java 中的包非常相似——如果你之前接触过 Java 编程语言。简单来说,PHP 项目中的目录是类的分组。你可以在目录中分组相似的类。因此,你的控制器类可能位于控制器目录下,模型类位于模型目录下,配置文件位于config目录下,等等。目录很重要。考虑一下,如果你想要更改特定目录的名称,你需要重构它。你需要重命名它。因此,所有引用类的代码行(includeinclude oncerequirerequire_once)在你重命名特定目录后都将自动更新。

如何操作...

我们将要重命名的元素是目录和类;让我们逐一看看它们。

重命名一个目录

要重命名一个目录,请执行以下步骤:

  1. 为了重命名一个目录,你需要右键点击上下文菜单并选择重命名选项。

  2. 在提供新名称时,你可以选择是否让这个更改渗透到整个项目中,无论这个目录在哪里被引用。

  3. 您还可以选择是否要替换注释和字符串中的出现。这在上面的屏幕截图中有展示:重命名目录

注意

如果你想要查看与这个目录对应的哪些出现,你可以选择预览按钮,或者直接重构更改。一旦你重构了更改,你就可以坐下来专注于进一步的开发计划。

重命名一个类

有时候,即使最好的计划也不能保证万无一失。你可能已经开始向东走,但由于风向,你感觉向东南走是一个更好且可行的选择。计划被破坏了吗?当然不是——需要一些修正,然后你就可以继续前行了。

这里有一个用例——你计划做一些Dish(菜肴),然后去了厨房,但发现关键的食材缺失。你会怎么做?继续饿着?当然不是...你会继续做一些其他的Dish。为了继续,你会尝试重用你在PizzaDish中使用的某些逻辑。从技术角度来说,你需要重命名(重构)你的类。

它是如何工作的...

为了做到这一点(重构你的类),你需要将光标放在类名上,访问右键上下文菜单,并选择重命名。你可以进行预览来检查哪些出现将被更改,一旦你确信,你可以进行重构

简单,不是吗?确实如此。

在这种情况下,重构将看起来如下面的截图所示:

如何工作...

更多...

到目前为止,我们已经熟悉了重命名元素。现在,是时候看看如何重命名一个方法了。

重命名方法

在 PhpStorm 中,对于方法的重构,你可以精细控制对方法名称或方法签名的更改。要更改方法名称很容易。类似于重命名目录和重命名类,你需要将光标放在目标方法名称上,访问右键上下文菜单,然后进行重命名。你可以在指定的框中应用更改。如果你想预览,你可以预览,或者你可以重构,PhpStorm 会愉快地将更改传播到所有出现的地方。

重命名成员变量

在所有提供的重命名标准和解释中,重命名成员变量是最典型的,并且需要处理上最多的成熟度。简而言之,这是一个“小心处理”的情况。变量可以是局部的、全局的或基于范围的。你可能需要一个变量名$salt,用于将盐这种成分添加到PizzaDish中,另一个$salt用于算法目的——比如说为了向你的密码中添加随机字符,使烹饪菜肴的容器更加安全。因此,你希望有一些盐来烹饪你的菜肴,同时也防止别人吃掉它。

注意

为了谨慎地重命名变量,步骤与前面描述的相同——增加的是警告小心。你需要将光标放在变量名称上,访问右键上下文菜单,并选择重命名,PhpStorm 将显示所有出现。你可以从可用列表中选择,并选择性地重命名所需的出现的变量。

参见...

你也可以参考前几节中关于重命名方法和重命名目录的内容。

改变方法签名也不困难。在复数情况下,你可能会意识到传递一个额外的参数就能达到目的。所以,你有了 PhpStorm 的魔法棒,可以非常容易地施展魔法来实现这一点。

你可以从将光标放在方法名称上,访问右键上下文菜单,并选择更改方法签名开始。魔法开始了。

PhpStorm 为你提供了许多选项来更改目标方法的签名。你可以参考前面的章节,其中详细描述了如何更改方法签名。

小贴士

为了避免仅仅为了添加或删除参数而更改方法签名,您可以使用 PHP 的 func_get_args(),这样可以使您的方法独立于参数的麻烦。因此,您只需要创建一个不带参数的方法,并使用 func_get_args() 来获取所有参数,1、5 或甚至 35 个参数都很容易。您可能会问“为什么我们一定要用参数呢?”这个答案相当简短。您应该对 PHP 解释器表示同情;在这种情况下,它需要进行更多的处理。

复制元素

目录包含类,类包含方法和变量,方法包含变量,并且方法使用变量。

需要证明的观点是,一切都在某种程度上相互关联。您同样可能想要复制一个目录,就像您想要安全地将一个类复制到当前位置或声明之外的其他位置一样。

如何操作...

复制一个目录意味着在某个地方,某个概念发生了变化,这导致了类的重新分组。因此,最好再思考一下。如果您仍然决定这样做,您需要执行以下步骤:

  • 前往 项目视图Alt + 1),突出显示目标目录,访问右键单击上下文菜单,转到 重构,然后选择 复制 选项。PhpStorm 将要求您提供详细信息。这些详细信息将是新名称,以及您希望将目录复制到的目标目录。PhpStorm 将为您复制。

还有另一种方法可以达到相同的效果,针对目录:

  • 您也可以通过传统的 Ctrl + CCtrl + V 组合直接将一个目录从一个位置复制到另一个位置。

对于目录,它创建相同的效果,区别在于它们工作的方式。重构是 PhpStorm 复制的一种更优雅的方式;它不会将任何内容保存到剪贴板中。

它是如何工作的...

复制更像是一种操作系统方法。它将名称作为字符串值复制到剪贴板中。因此,您可以在编辑器中直接粘贴名称,在项目视图中直接粘贴目录。有趣,不是吗?

复制目录的外观如下所示:

如何工作...

那么,您应该选择哪一个呢?这取决于您。做任何一项,但请确保您遵循 不要重复自己DRY)的原则。

还有更多...

到目前为止,您已经熟悉了复制元素,现在是时候转向复制一个类了。

复制一个类

复制一个类在大多数情况下意味着复制其中的业务逻辑。在软件工程中,这个过程被赋予了一个复杂的名称,即现成开发。你可以欺骗所有人,但不要欺骗自己,你只是一个模仿者!复制类的目的是为了重用其中大部分现有的业务逻辑。然而,更多的逻辑被注入到类中以膨胀它。要复制一个类并开始你的现成开发,你需要通过访问右键单击上下文菜单并选择复制选项来复制一个类。对话框是相似的。问题也是相似的。效果是相似的。结果却不同。在这里,一个类从一处复制到另一处。

注意

就像你可以对目录进行复制粘贴一样,你也可以对你选择的类执行完全相同的操作。遵循操作系统的复制方式,要复制的类的名称也被放在了剪贴板上。如果你在编辑器中粘贴它,类的名称将被粘贴,如果你在项目视图中粘贴类的名称,整个类将在项目视图中被粘贴到所选位置。

移动元素

任何敏锐的软件工程师都知道剪切或复制和粘贴的重要性。与这个重要声明相关的信息如下:

  • 剪切和粘贴比复制和粘贴更快。然而,剪切和粘贴会改变所选元素的位置。而复制则保持原始位置不变,剪切则将其从原始位置移除。

任何有经验的软件工程师都会通过过去的经验拥有这种知识。

如何操作...

我们已经讨论了重命名元素、复制元素,现在,是时候移动一个目录了。

移动目录

如果你确定你的架构在某处发生了变化,以至于你的分组发生了变化,你应该准备好将整个目录(你的分组)移动到另一个分组(另一个目录或位置)。为了移动一个目录,你需要执行以下步骤:

  1. 你需要转到项目视图,选择所需的目录(也称为分组),访问右键单击上下文菜单,并选择移动选项。

  2. PhpStorm 将询问你一个问题,即你希望将所选目录移动到何处。

  3. 一旦你回答,PhpStorm 将处理其余的事情,你的任务将完成。

移动类

你想把你的类移动到另一个目录(或命名空间、文件夹或分组,用最通俗的话说),理想情况下是在你匆忙开始开发而没有适当计划的情况下,现在你意识到你想象中的实体不是最佳解决方案。好吧,不要责怪自己。相反,使用 PhpStorm 帮助你通过将其移动到更合适的位置来重构你的类。执行此操作的命令是相同的。

使用右键单击上下文菜单,进行重构,然后移动。指定目标目录的位置,您希望将此类移动到该位置。PhpStorm 将在操作完成后提示您。

移动方法

将方法移动到其他类的前提有两个。一个是最常见的:您应该清楚自己在做什么。另一个是要移动的方法必须是静态的。如果不是,PhpStorm 将通过提示“不支持移动非静态方法”来警告您。

如何操作...

要移动方法,请执行以下步骤:

  1. 只需将光标放在方法名称上,从右键单击上下文菜单中访问重构选项并移动。

  2. 您需要提供目标类的名称,您希望将此方法移动到该类。

  3. 您可以选择预览此更改(移动)将影响哪些出现。

  4. 一旦您对建议的结果感到满意,您就可以重构方法。目标类现在将包含您刚刚移动的方法,如下截图所示:如何操作...

移动变量

将成员变量移动到其他类既简单又非常重要,从架构角度来看。变量通常表示现实世界中的属性。因此,如果您为PizzaDish计划了糖,您肯定会非常快速地将糖从PizzaDish移动到其他菜肴,比如Cookie。就像方法一样,您只能将静态成员移动到其他类。

如何操作...

从右键单击上下文菜单中选择重构,然后选择移动

如果要移动的当前成员变量在当前类中是私有的,则移动操作将成员转换为公共。

在执行移动操作之前,PhpStorm 会警告您,如下截图所示:

如何操作...

小贴士

无论您在哪里放糖,您都应该始终尝试使用语法糖,因为它可以稍微减轻一些文档负担。

PhpStorm 说“您的知识水平已提升至 200%”。您必须说“太棒了”!...200%...如何?您已经知道如何在您熟悉的操作系统下复制或剪切粘贴。100%的知识...现在您知道了使用 PhpStorm 进行相同操作的方法,并且增加了 100%的知识。所以,应用简单的数学,您的知识水平现在是 200%”

注意

除了通过移动进行重构之外,您还可以通过将任何程序结构或标识符在代码中移动来玩转您的代码。这不仅仅是重构,而是简单的移动。PhpStorm 可以配置为尊重您的if-else或其他代码块。要移动一行代码,只需将光标放在所需的行上,并使用神奇的快捷键Alt + Shift + 向上向下。您的行将向上或向下移动。此操作对代码选择也有效。

删除元素

从代码库中删除代码本身是一项非常大胆的任务。要求程序员删除代码中的业务逻辑就像要求他捐出一个肾脏一样!

准备工作

PhpStorm 通过提供安全删除选项来简化这个过程。您可以通过重构来删除代码中的元素。这个重构会找到所选元素的所有出现,一旦您要求它继续,PhpStorm 就会愉快地删除项目中该元素的所有选定出现。

如何操作...

要删除文件,您需要遵循以下步骤:

  1. 在目标文件名上放置光标后,访问右键单击上下文菜单。

  2. 选择安全删除选项。然后,PhpStorm 会询问您是否想查看代码中的注释和字符串,如下面的截图所示:如何操作...

  3. 如果您继续,PhpStorm 会通知您删除文件时可能出现的任何潜在问题。

  4. 您可以通过选择查看用法选项或按Alt + F7来查看那些处于雷达之下的文件列表。

  5. PhpStorm 会提供一个列表,列出所有引用您要删除内容的文件。如果您改变主意,可以重新运行安全删除。如果您决心已定,可以继续删除。如果您选择不删除,可以取消整个过程,如下面的截图所示:如何操作...

  6. 如果您对删除过程的结果感到满意,可以选择无论如何删除选项。

它是如何工作的…

一旦确定,PhpStorm 将执行以下操作来删除文件:

  • 在要删除的文件中找到元素

  • 在项目中的其他文件中找到元素的出现

  • 从项目中的其他文件中删除出现

  • 删除最初选定的文件

在项目中搜索代码

很少有人会记住每一行代码。如果您的经理因为您没有记住最后修改的那一行而责备您,您只需微笑并继续使用 PhpStorm 工作。当您在输入时忘记无线键盘放在哪里,或者在驾驶同一辆车时忘记车钥匙放在哪里,您可能会忘记任何事情。人类可以忘记任何事情。人脑以无法解释的方式行事。

准备工作

有 PhpStorm 在身边意味着您可以忘记您的代码。即使您对像 Pizza 或 Dish 这样的关键字有一些记忆,在 PhpStorm 中也有可以找到所有这些关键字引用的设施。您还没有被 PhpStorm 的这种强大功能所说服吗?请继续关注更多信息。

在 PhpStorm 中,有一个在路径中查找工具。从技术和使用角度来看,这是 PhpStorm 提供的一项最佳功能。从技术角度来看,它被编程为既智能又快速。如果你搜索到 PhpStorm 认为可能成为问题的内容,它会通过显示警告来提醒你,如下面的截图所示:

准备中

如何做...

在项目中搜索一个项目的旅程从简单且易于记忆的键盘快捷键开始,Ctrl + Shift + F。一旦你启动了命令,你将被要求提供你的搜索参数。

你提供的第一个选项是你想要搜索的字符串。这是搜索能够继续的最基本和最重要的要求。

如果你没有提供任何文本,查找按钮无法执行搜索。你在这里输入的文本应该有策略地提供,以节省你和 PhpStorm 的时间。以下具有多个视角的示例是最好的。假设你非常饿,需要知道如何烤披萨。你的搜索字符串将是pizza

你可以缩小搜索条件,如下面的截图所示:

如何做...

在弹出窗口中有一个目录单选按钮。你可以选择它来让 PhpStorm 知道它必须只选择特定目录内。当你指定目标目录的路径时,PhpStorm 将执行相同的搜索任务,但这次它将使用缩小后的搜索条件。这里值得注意的一点是,项目只是一个目录的集合,所以当你在一个项目中搜索时,你实际上是在一组目录和/或某些文件中搜索。当你选择一个目录时,因此使搜索更快,因为 PhpStorm 需要搜索的更少。懒惰的 PhpStorm!

如果目标目录内有子目录,你可以通过选择递归选项来告诉 PhpStorm 实际进入这些目录,如下面的截图所示:

如何做...

然而,你可能仍然需要浏览许多结果来找到目标。

如果你想要告诉 PhpStorm 在特定文件中搜索,你可以通过从自定义范围旁边的下拉框中选择以下值之一来实现:

  • 项目文件:搜索将限制在项目文件中。

  • 项目和库:搜索将包括项目目录和项目中使用的库。

  • 项目测试文件:搜索将查看项目的测试文件。

  • 打开的文件:搜索将查看当前在编辑器中打开的文件。

  • 之前搜索结果中的文件:搜索将查看之前搜索中使用的文件。这意味着 PhpStorm 会记住你搜索了什么。

如果你想要自己的自定义搜索标准,你也可以做到。PhpStorm 将记录你的首选项,并允许你随时切换到它们进行搜索。为此,有一个在自定义下拉菜单旁边的按钮。当你按下它时,你将被要求保存你的首选项,如下面的截图所示:

如何做...

一旦你点击保存按钮,你的首选项将开始出现在同一下拉菜单下的自定义范围内。如果在未来的某个时刻,你需要更改你刚刚创建的自定义搜索范围,你需要遵循相同的步骤。将出现相同的表单,你可以从那里编辑你的首选项。

它是如何工作的…

你还有许多要搜索的内容。人的大脑非常懒惰,它总是寻找消耗更少能量的更好的替代方案。在项目内部搜索有点太多。你仍然需要手动查看搜索结果,然后决定你想要的披萨版本,如下面的截图所示:

它是如何工作的…

你的pizza可能是一个Pizza。在这种情况下,你需要选择区分大小写选项。PhpStorm 将区分Pizzapizza

注意

如果你确定你只想搜索披萨,你应该选择仅全词选项。这样,PhpStorm 就会知道它只能搜索披萨,而不是像pizzadishpizzacookingpizzacooked这样的类似词。

如果你只想搜索注释中(包括 PHPDoc)pizza的出现,你需要选择仅注释选项。

如果你只想找出包含单词pizza的字符串数量,你应该选择仅字符串字面量选项。PhpStorm 将只查看字符串常量。

更多内容…

搜索最重要的部分出现在你决定要搜索所有以pizza结尾、在中间或开头的案例时。到目前为止,正则表达式可能已经开始响起铃声。如果你对以披萨开头的所有单词感兴趣,你的搜索字符串可能类似于^pizza。然后你需要选择正则表达式选项。显然,你将想要创建更多和更多的用例,以便掌握正则表达式(RegEx)的艺术。有关正则表达式使用的帮助,你可以前往 PhpStorm 的帮助部分。为了方便,相同的表格已经复制在这里。熟悉 Java 的人会感到宾至如归!

比较文件

代码的更改是一个噩梦。全世界开发者的社区都一致认为这一点。为了控制更改,有版本控制系统可用。这些系统可以在你将更改的文件上传到版本控制系统时详细显示文件何时发生变化。然而,谁对你的本地工作副本所做的更改负责?你将如何跟踪哪个更改导致你的代码崩溃?

准备工作

您可以使用文件比较功能。由于 PhpStorm 记录了您在编辑器上执行的每一个活动,您可以通过比较不同时间线上的问题文件来找出实际的非工作代码。如果您觉得时间线在这里很陌生,您可能会更容易知道 PhpStorm 实际上是根据时间戳保存您的本地副本版本。如果在某个时间点,您的代码停止工作,撤销操作也无法帮助,您可以使用文件比较来查看时间线,并将历史文件与当前文件进行比较。这样,您就能识别出是哪个更改阻止了您的代码执行。

如何操作...

为了查看本地历史记录并将当前文件与历史文件进行比较,请执行以下步骤:

  1. 您需要访问右键点击上下文菜单,选择本地历史选项,并选择显示历史选项。

  2. 根据文件历史的时间戳,您将获得差异的详细信息,如下截图所示:如何操作...

  3. 同样,您也可以比较两个文件。您需要转到项目视图,选择感兴趣的文件,点击右键访问上下文菜单,并选择比较 2 个文件选项。您将看到一个类似的比较窗口,显示您所选两个文件之间的任何差异。

  4. 蓝色线条显示的是更改的内容,绿色线条显示的是新内容,红色线条显示的是冲突内容。

  5. 有方向箭头(>><<),它们指示哪些更改应该传递到哪个文件,如下截图所示:如何操作...

它是如何工作的...

如果您不喜欢颜色,您也可以通过导航到文件 | 设置 | 编辑器 | 颜色与字体 | 差异来更改它们,如下截图所示:

它的工作原理...

有时候,您必须忍受他人对软件工程实践的违规行为。当您在团队工作时,这种情况就会出现。团队成员不小心对代码进行了更改并将其推送到代码库。作为高级程序员,您被要求采取行动并修复它。但您对如何进行操作毫无头绪。您可以使用相同的差异(或文件比较系统)来比较存储库中的文件。一旦您将其与最后几项修订进行比较,您将立即发现错误,并能够修复它。这样,您将证明您作为程序员的实力!感谢 PhpStorm。

注意

无论您进行何种比较,无论您比较哪些文件,默认的键盘快捷键是Ctrl + D。希望您能记住这个快捷键。记住这个快捷键仅适用于更改历史窗口打开时进行比较。

使用比较恢复元素

除了文件比较,如果您希望恢复已删除的文件或文件夹,这个差异系统可以提供极大的帮助。您只需记住已删除文件最初所在的目录名称。这会与问题相关吗?是的,会的。如果您查看文件夹的本地历史记录,您将能够看到对目录执行了哪些操作。

准备工作

操作可以是任何东西:新文件或文件夹,某些文件或文件夹的更改,文件或文件夹的删除,等等。现在您可以安全地感谢 PhpStorm 监控您所执行的每一个操作。

一旦您找到您最缺少的资源,您可以将时间戳回滚到灾难性更改之前。

如何操作...

恢复更改的最简单方法是使用键盘快捷键Ctrl + Z撤销。您将能够撤销文件中的上一个编辑,直到您关闭它。对于项目也是如此。

您可以撤销删除、重命名或项目中的任何更改。这些都是安全的,PhpStorm 会记录所有历史记录。

它是如何工作的...

文件的恢复基于时间戳,或者可以使用 SVN 或其他版本控制工具进行恢复。我们已经讨论过撤销在软件工程中的有用性,但其工作原理基于您的操作系统,这超出了本书的范围。

参见

此恢复过程已在恢复已删除资源中描述。

注意

唯一的前提是删除过程应在 PhpStorm 内部执行。如果资源是在外部删除的,PhpStorm 将无法提供帮助。

设置运行配置

在学习如何在 PhpStorm 编辑系统中编码后,您现在应该能够执行您的代码了。不,不是!这里并没有假设您不知道如何运行代码——这里讨论的视角是 PhpStorm。现在您可以再次阅读提到的声明。

如何操作...

  1. 可以为项目范围内的文件设置运行配置。要配置这些设置,您需要从主菜单中选择运行 | 编辑配置。将出现一个对话框,它会向您提出许多问题。这些答案将通过提供更快执行代码的方式帮助您。

  2. 一旦您打开设置区域,您需要广泛关注您感兴趣的方法。如果您没有指定任何设置,PhpStorm 将确定您所编写的脚本的类型。PHP 脚本设置是对您曾经通过命令行执行 PHP 脚本并通过提供命令行参数、指定解释器选项或环境变量(如果您想做一些疯狂的事情)进行操作的情景的模拟。

您指定的参数是您的 PHP 脚本的命令行参数。

解释器选项是你用来提供给你的 PHP 解释器的选项。一些常用的开关会让你回想起那些痛苦的日子:-a-v--info等等。

以下是一个可用选项列表:

选项 描述
-a 作为交互式 shell 运行。
-c<path>&#124;<file> 在此目录中查找 php.ini 文件。
-n 不会使用 php.ini 文件。
-d foo[=bar] 定义 INI 条目 foo 的值为 bar
-e 为调试器/分析器生成扩展信息。
-f<file> 解析并执行 <file>
-h 这是帮助信息。
-i 这将给出 PHP 信息。
-l 仅进行语法检查(lint)。
-m 显示编译在模块中的代码。
-r<code> 运行 PHP <code>而不使用脚本标签<?...?>
-B<begin_code> 在处理输入行之前运行 PHP <begin_code>
-R<code> 对每一行输入运行 PHP <code>
-F<file> 对每一行输入解析并执行 <file>
-E<end_code> 在处理所有输入行之后运行 PHP <end_code>
-H 隐藏传递给外部工具的任何参数。
-S<addr>:<port> 使用内置 Web 服务器运行。
-t<docroot> 为内置 Web 服务器指定文档根 <docroot>
-s 输出 HTML 语法高亮源代码。
-v 这将给出版本号。
-w 输出去除注释和空白符的源代码。
-z<file> 加载 Zend 扩展 <file>.
args... 脚本传递的参数。当第一个参数以-开头或脚本从stdin读取时,使用-- args
--ini 显示配置文件名称。
--rf<name> 显示关于函数 <name> 的信息。
--rc<name> 显示关于类 <name> 的信息。
--re<name> 显示关于扩展 <name> 的信息。
--rz<name> 显示关于 Zend 扩展 <name> 的信息。
--ri<name> 显示关于扩展 <name> 的配置。

保存设置后,你的 PHP 脚本将准备好运行。

注意

值得注意的是,这仅仅是 PhpStorm 执行命令行 PHP 脚本的一种方式。如果你记得 PhpStorm 中有一个终端视图可用,你将很容易联想到你同样可以在终端中完成相同的任务。

另一个值得你关注的配置是 PHP Web 应用程序设置。对于普通人或非程序员来说,它似乎表明 Web 编程是一件轻而易举的事情。

拒绝邪恶之人的建议,不效仿罪人的榜样,是幸福的。

它是如何工作的...

认为 Web 编程很容易,就像认为每个人都能烤出美味的披萨一样。记住,美味是关键词。要处理执行基于 Web 的应用程序的挑战,你需要告诉 PhpStorm 一些基本设置的事实。你需要在此处指定的设置是:

  • 需要指定一个有效的网络服务器,您的应用程序将在该服务器上启动。要配置新的服务器,在提供的下拉菜单右侧有一个小方块按钮。点击该按钮,您将被带到全新的设置区域,在那里您需要设置网络服务器。

    复杂!去找那些说网络编程很简单的人。您对他们可以随意行事,但在这里,使用 PhpStorm,您需要指定设置网络服务器的配置。要设置新的网络服务器,您需要指定将来(无论远近)将用于访问此网络服务器的名称。您需要设置主机名(您可能使用 localhost 或127.0.0.1)和端口号(最常见的情况将导致您将80作为这里的值)。您还可以在这里指定调试器。

    默认情况下,PhpStorm 支持Xdebugzend-debugger。不要因为不知道调试器是什么而挠头。它将在本书的后面讨论。一些开发者更喜欢通过只在其中放置符号链接来保持网络服务器文档根的清洁。这些符号链接指向本地磁盘上的其他位置。这样做的原因是文档根可能不提供写入目录所需的足够权限。您显然比服务器文档根更容易控制自己的目录。如果您在文档根内部有符号链接,您也可以告诉 PhpStorm。表格的左侧是您的项目实际保存的路径,右侧是文档根下的符号链接。

    您可以指定起始 URL(口语中的基本 URL)。这很简单。

  • 需要指定用于查看网络应用程序的浏览器。您可以从预定义的浏览器列表中选择浏览器。如果您认为需要专门针对某些浏览器来查看您的代码,您需要转到Web Browsers设置。这可以通过两种方式实现:

    • 浏览器下拉菜单右侧的方块按钮。您需要填写的是与浏览器相关的配置。您可以告诉 PhpStorm 跟随所选默认浏览器背后的操作系统。您可以通过选择可执行文件所在的路径从 Firefox、Internet Explorer、Safari、Chrome 或 Opera 中选择。您还可以设置一个浏览器为活动或非活动状态,并使其成为默认浏览器。您可以使用浏览器设置与 PhpStorm 一起使用。

    • 另一种方式是通过文件 | 设置 | Web Browsers。这两个路径都将您带到同一个目的地,如下所示:

    工作原理...

    全球有众多可用的网络浏览器。您可以选择您喜欢的网络浏览器,并将其设置在这里以便在 PhpStorm 中使用。

还有更多...

你还可以设置一个预运行配置,通过设置一些在应用程序执行之前执行的命令。有一些配置选项可用。你甚至可以根据这个配置创建自己的新的 PhpStorm 工具,并在此处使用它,如下面的截图所示:

还有更多...

这就是将你的网络应用程序设置为在 Web 服务器上执行并在 Web 浏览器中查看的全部内容。要执行你创建的网络应用程序代码,你需要在编辑器中的文件上右键单击并选择在浏览器中打开。搞定!

运行你的代码

有意进入 PHP 的世界,你也步入了网络编程的世界,因为 PHP 也是一种流行的网络编程语言。用 PHP 编写的应用程序必须在两种介质之一中执行。

准备工作

你需要一个安装了 PHP 模块的 Web 服务器,如 Apache。如果你需要一个 Web 服务器,你很可能正在创建一个将在 Web 浏览器上运行的网络应用程序。

如何操作…

要运行 PHP 代码,你只需要学习一个快捷键 Ctrl + Shift + F10。其余的由 PhpStorm 来处理。

代码将根据你设置的配置来执行。有关执行 PHP 代码的更多详细信息,你也可以参考上一章。

然而,如果你没有在 PhpStorm 中执行 PHP 代码的先验经验,你也不愿意尝试新事物,你可以求助于老式方法。

它是如何工作的…

你可以使用 PhpStorm 作为开发系统和文件传输系统,将你的代码上传到 Web 服务器,在那里你可以立即测试代码。前提是 Web 服务器应该是一个开发服务器,你只需要修改 PHP 代码。

这听起来是不是太老式了?也许吧。继续阅读。

如果开发服务器是你的本地机器,这将是一种低效的工作方式。如果你的开发服务器不在你的本地机器上,即使它在本地网络中,通过网络传输文件也会存在延迟。显然,作为一个开发者,你无法承担这种延迟,除非业务需求是这样的,你不能在本地机器上设置整个系统。

小贴士

在所有其他情况下,建议你在你的机器上设置一个开发服务器的本地副本。

跟上新的潮流。PhpStorm 很棒!

第四章:集成框架

在本章中,我们将涵盖以下主题:

  • 使用 Symfony 进行烹饪

  • 使用 Symfony 创建控制器

  • 使用 Symfony 创建模型

  • 使用 Symfony 创建视图

  • 使用 Yii 框架创建模型

  • 使用 Yii 框架创建控制器

  • 使用 Yii 框架创建视图

  • 使用 Zend 框架创建模型

  • 使用 Zend 框架创建控制器

  • 使用 Zend 框架创建视图

简介

在您开始之前,试着做一些自我反思作为作业。您相信重新发明轮子吗?您相信增加技术债务吗?如果您的回答是肯定的,您可能需要完全跳过这一章。在其他所有情况下,您应该使用框架。框架对您来说很好,它们有帮助,节省时间,节省精力。

让我们回到问题。什么是技术债务?它是指公司因技术架构设计得如此之差,以至于在将来维护系统需要更多的努力或人力(从而金钱)的金额。什么是重新发明轮子?它是指投入更多努力去完成过去已经完成过的任务的过程。

请您停止挠头?这并不是火箭科学。与软件工程的类比相当简单。您可能花费时间在编码琐碎的任务上,比如为每个创建的项目进行用户输入验证和密码验证。虽然这首先是一种任务的重复,但这是您代码中最脆弱的部分。这种脆弱性不仅来自一般的攻击者,还来自某些非常简单的错误,例如没有清理代码。

您需要策略性地采取行动。这种重新发明轮子的行为并非没有成本。您是一位高薪的开发者(因为您购买了 PhpStorm 许可证(有意为之)。您的计费机构将花钱让您完成工作。如果您做的工作容易出错,计费机构将不得不花费更多金钱来修复和/或维护同一项目。因此,该机构注定会在未来花钱,因此有技术债务。

请使用框架。您可以使用框架中的块和片段快速构建代码的块和片段,从而加快您的开发过程。您将接触到用于常见任务、数据库查询和输入清理等的函数库,仅举几例。然而,选择框架的决定需要深思熟虑。

仍然有一些悬而未决的问题浮现在脑海中。您需要坚持下去,并保持关注,以获取大量重要信息。PhpStorm 可以轻松嵌入三个框架:Symfony、Yii 和 Zend,按照它们名称的字典顺序排列。

使用 Symfony 进行烹饪

Symfony 是一个免费的 MVC Web 应用程序框架,用于 PHP,并遵循 MIT 许可证发布。

要开始使用 Symfony,您需要在您的本地机器(也称为您的本地服务器)上安装 Symfony。生活永远不会让您轻松呼吸。您必须从两个(或更多)路径中选择以继续。PhpStorm 也是如此。

准备工作

改变往往会导致混淆,因此最好在 Symfony 目录结构中做出少量更改,然后跳转到创建新的控制器。您在目录<Project-Root>/src/Acme/DemoBundle/Controller中创建一个新的控制器类。命名为CookingController.php。以下是一些需要遵循的规则:

  • 默认情况下,您应该在名称中创建一个以Controller结尾的控制器

  • 每个控制器都应该扩展在命名空间Symfony\Bundle\FrameworkBundle\Controller\Controller中定义的Controller

  • 控制器应在命名空间Acme\DemoBundle\Controller中定义

由于您将需要将方法的路由作为操作,因此您需要使用命名空间Sensio\Bundle\FrameworkExtraBundle\Configuration\Route

您需要在配置文件(具有.yml扩展名的文件)中定义一个路由,以便 Symfony 确切知道您的控制器在哪里。

如何做到这一点...

要安装 Symfony,您可以从 Symfony 网站上的简单存档下载中选择,或者使用 Composer 进行安装。Composer?是的,它与第二章中描述的相同系统,PHP 开发,以及一些关键词来刷新您的记忆,如 composer.json、vendor 目录等。

执行以下步骤:

  1. 如果您想从网站上下载安装 Symfony,您需要访问symfony.com/download,选择任何存档格式,并将存档下载到磁盘上。

  2. 一旦将存档下载到磁盘上,您可以将解压缩的目录移动到您的 Web 服务器文档根目录内,并在 PhpStorm 中打开它。以下有两点需要注意:

    • 如果您不想将项目作为 Web 项目,则无需将其移动到 Web 服务器的文档根目录中。

    • 如果您想创建一个基于 Web 的项目,您也可以将解压缩文件夹放在任何地方。然后您可以在 Web 服务器文档根目录内创建一个符号链接,指向这个解压缩文件夹。这样做是为了保持系统整洁,您明白的。

要在 PhpStorm 中打开项目,您需要转到文件 | 打开并打开您保存 Symfony 目录的路径。

Composer 方法可能有点长,但仔细阅读 PhpStorm 食谱的读者不必担心,因为如何使用 Composer 的信息已在第二章中提供,PHP 开发。执行以下步骤:

  1. 您需要指定symfony/framework-standard-edition作为包名,如下截图所示。PhpStorm 将显示具有相似名称的包列表。

  2. 您需要指定版本号,PhpStorm 就会一切就绪。它会为您下载所需的依赖。

    小贴士

    您应该确保有一个稳定的互联网连接。

    如何操作...

  3. 一旦框架下载完成,您可以重启您的 IDE(非强制要求),让 PhpStorm 在为您下载框架的重任之后轻松一下。一旦重启,PhpStorm 就能识别出需要集成的框架。PhpStorm 会引导您完成框架集成的过程。

  4. 您可以通过提供详细信息来告诉 PhpStorm 目录及其包含的内容类型。您只需从下拉菜单中选择一些值,如下面的截图所示:如何操作...

因此,您就可以使用 Symfony 了。在项目根目录提供了一个readme.md文件。鼓励您阅读它,并按照其中提供的清单进行操作。

它是如何工作的...

Symfony 框架遵循模型-视图-控制器框架。除了 MVC 带来的所有好处外,功能模块化也是一个主要优势。因此,您将所有数据库相关的功能放在模型中,所有业务逻辑放在控制器中,所有与展示相关的功能(生成 HTML)放在视图中。所以,为了深入了解 Symfony,您首先需要了解目录结构。

更多内容...

目录结构是项目的骨架,在开始之前了解目录结构非常重要。让我们看看 Symfony 的结构。

Symfony 的目录结构

当您下载并安装 Symfony 时,您会默认获得一个目录结构。有五个可见的目录:appbinsrcvendorweb目录。

app文件夹设计用来存放应用程序特定的资源。这些资源包括config目录中的数据库连接配置等。logs目录旨在存放 Symfony 框架应用程序需要写入的日志。缓存目录旨在存放运行应用程序所需的文件和资源的缓存版本。缓存版本比常规版本更快,且是只读保护的。资源目录设计用来存放如视图渲染页面等资源。

bin文件夹设计用来存放项目所需的二进制文件(如.sh文件)。由于这些文件的性质,它们需要可执行权限以便能够独立执行并完成预定的任务。在提供文件和文件夹的执行权限时,您需要小心。

src 文件夹被设计用来存放项目所需的 PHP 源代码。这些 PHP 源代码可以是任何东西:你的模板、类,以及你认为与你的项目相关的任何内容。

web 文件夹被设计用来保存所有需要在网络浏览器中渲染的内容。这些内容包括 HTML、JavaScript、CSS、图片、图标、精灵、robots.txt 等,根据项目需要随时使用。

vendor 目录被设计用来保存所有项目运行所需的第三方工具。这是一个非常出色的功能,因为它将第三方代码保存在一个独立的隔间中,从而保护它们免受意外编辑。

这里值得注意的是,一个框架为你设定了规则。如果你坚持这些规则,你将站在胜利的一方。一个例子是,假设你从互联网上下载了一个插件 X,你的代码的一部分依赖于它,项目整体有一个 config 目录。有很大可能性你可能会修改或覆盖 config 文件。框架将阻止你这样做。它是如何做到的?它会指示你,供应商目录内的配置不得被干扰。如果你仍然故意或无意地继续进行更改,每个保证都有其限制。

注意,"被设计用来存放"意味着这是默认的意图。你显然可以随意将你的类存储在任何地方。

在你设置好目录结构之后,是时候真正地动手了。朋友们,罗马人,同胞们!卷起袖子,并记住你所看到的一切。

app 文件夹内部,有一个 cache 文件夹。正如之前所述,它用于缓存一些预先准备好的内容,以便可以非常快速地渲染。缓存可以应用于常用的元素,例如图片、字符串、JavaScript、CSS 以及某些预处理数据。由于在 Web 服务器上执行的 PHP 会写入缓存,因此运行 Web 服务器(是的,你没听错)的用户需要写入 cache 文件夹的权限。对于日志目录也是如此。你需要将这两个文件夹的权限设置为 777。你可以做得更好。你可以更改这两个目录的所有权,使它们现在由 www-data 或 Apache 用户(Linux 环境下的用户名)拥有。尝试使用 chownchmod 命令。无论你做什么,都要确保你做对了。所有权/权限更改是可能引起问题的行为,所以不要在感到困倦时进行更改。

你喜欢在泥潭中玩耍吗?还有更多的泥潭在等着你。

回想一下历史上的某个时刻,你非常饿,试图用一些奶酪、盐、辣椒和番茄(作为备用配料)烘焙披萨。还记得吗?那是一种自由式烹饪。如果你想在生活中有更多有纪律的冒险?尝试遵循 Symfony 的方式。

使用 Symfony 创建控制器

所以你首先需要创建一个新的控制器。这个控制器将负责决定你如何烹饪你的披萨。

改变往往会导致困惑,所以最好是只在 Symfony 目录结构中做少量更改,然后直接创建一个新的控制器。

如何做到这一点...

在目录<Project-Root>/src/Acme/DemoBundle/Controller中创建一个新的控制器类。命名为CookingController.php。有一些规则需要遵循:

  • 默认情况下,你应该在名称中带有后缀Controller的控制器。

  • 每个控制器都应该扩展在命名空间Symfony\Bundle\FrameworkBundle\Controller\Controller中定义的类Controller

  • 控制器应该定义在命名空间Acme\DemoBundle\Controller中。

  • 由于你需要将方法作为操作进行路由,因此你需要使用命名空间Sensio\Bundle\FrameworkExtraBundle\Configuration\Route

  • 你需要在配置文件(一个以.yml扩展名结尾的文件)中定义一个路由,以便 Symfony 确切知道你的控制器在哪里。

    小贴士

    你可以稍后定义路由。

所以,你的第一个控制器看起来像以下代码:

namespace Acme\DemoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
class CookingController extends Controller {
  /**
    * @Route("/", name="_cooking")
    * @Template()
  */
  public function indexAction() {
    return array();
  }

  /**
    * @Route("/nameDish/{dishname}", name="_cook_dish")
    * @Template()
  */
  public function nameDishAction($dishname) {
  return array('name' => $dishname);
  }
}

并且 YML 文档的内容(位于<Project-root>/src/Acme/DemoBundle/Resources/config/routing.yml)将被(附加):

_cook:
resource: "@AcmeDemoBundle/Controller/CookingController.php"
type: annotation
prefix: /cook

它是如何工作的...

人类的大脑是一个非常懒惰的机器。它一看到任何技术细节,就会开始感到困惑。为了消除疑惑,这里将进行解释。请耐心等待。我们从源代码开始,因为 PHP 是你更熟悉的东西。以下是工作原理。

代码从声明一个命名空间开始,这意味着你为这个控制器的元素声明了一个虚拟区域或边界。技术上,这被称为命名空间。

代码通过包含这样的命名空间来继续,这些命名空间用于基本的Controller和路由系统(用Route表示)。

如果你想包含一些表示层模板,你也可以使用模板引擎的命名空间。在 Symfony 的默认安装中,默认的模板引擎被命名为 Twig。

在这里,控制器最重要的一个方面是CookingController是一个控制器,因此它必然要扩展Controller类。

在类内部有一些简单的公共访问方法。你说这是不安全的吗?不,亲爱的!由于它们将通过网络浏览器提供,访问级别必须是公共的。

实际的烹饪过程从给你的菜肴起一个名字开始。为此,nameDishAction方法将菜肴名称作为参数。到目前为止,一切都很正常。

有这样一个注解@Route("/nameDish/{dishname}", name="_cook_dish"),给故事增添了转折。Route在动作和 URL 之间创建了一个映射。这是另一种形式的依赖注入。所以,动作的名称nameDish与 Symfony 系统的名称_cook_dish相映射。如果你更仔细地看,你还会看到它还定义了你将如何使用这个控制器。括号中指定的值是传递给这个动作的参数的占位符。

关于 YML 内容,值得一提的是,YML 实际上是 YAML,发音为 yamel。这类似于任何具有键及其对应值的标记语言。所以,你的资源将指示你刚刚创建的控制器名称,你的控制器将被引用的类型,以及需要在控制器中定义的动作前添加的前缀。

你刚刚创建了一个新的 Symfony 控制器来启动烹饪。顺便问一下,你还记得你上次使用依赖注入这个术语吗?

使用 Symfony 创建模型

应用程序是如何记住事物的?持久性是任何应用程序维持其状态的名称。为了有持久性,你需要有数据结构。从典型的工程角度来看,你可以使用模型——MVC 模式中的 M。

准备工作

记住,你有一些配料以及一些需要添加到你的披萨菜肴中的配料。所以,通常,你需要一个数组来存储(表示)配料和配料。这是前进并使用模型的绿灯。但故事中还有转折。Symfony 没有默认的模型系统。糟糕的设计?也许不是。它最初被设计成一个请求-响应系统。Symfony 期望你来完成这个目的。你可以自由地创建模型。

如何做到...

  1. 首先,在控制器同一级别创建一个新的目录。命名为Model。这是描述性命名,你看到了。

  2. Model目录内,使用 PhpStorm 的新类向导创建一个新的类。命名为CookingModel.php。并不是说 Symfony 不会接受除了/*Model$/之外的其他类名。

  3. 你被鼓励使用与默认 Symfony 名称相似的名字。你的模型将看起来像以下代码:

    namespace Acme\DemoBundle\Model;
    use Doctrine\Common\CommonException;
    
    class CookingModel {
      /**
        * Get the ingredients that will be added to your dish
        * @return array Containing the list of ingredients
      */
      public function getIngredients(){
        $ingredients = array('salt','cheese','');
        $ingredientCount = 0;
        try {
          while ($ingredientCount < count($ingredients)) {
            if ($ingredients[$ingredientCount] == '') {
              throw new CommonException("\nYou have run out of capsicum.");
            }
            $ingredientCount++;
          }
        } catch (CommonException $e) {
          $ingredients[$ingredientCount] = 'tomato';
        }
        return $ingredients;
      }
    
      /**
        * Get the toppings that will be added to your dish
        * @return array Containing the list of toppings
      */
    
      public function getToppings(){
        return array('pepperoni','mushroom','onion','spinach');
      }
    }
    
  4. 由于你刚刚创建了一个新的模型,除非它在控制器内部使用,否则模型将没有用处。回顾CookingController。它没有实际烹饪披萨的动作。Acme\DemoBundle\Model\CookingModel应该附加到控制器文件头部。当你添加所需动作时,你将做如下代码:

    /**
      * @Route("/startCooking/{dishname}", name="_start_cooking_dish")
      * @Template()
      * @param string $dishname The name of the dish to be cooked.
    */
    public function startCookingAction($dishname){
      $items = new CookingModel();
      return array(
        'dishname' => $dishname,
        'ingredients' => $items->getIngredients(),
        'toppings' => $items->getToppings()
      );
    }
    

它是如何工作的...

现在你已经有一些烹饪经验了,模型类相当简单。如果你还记得,模型的内容只是从PizzaDish类中智能复制粘贴过来的。

CommonException类的命名空间被用来捕获在烹饪过程中可能发生的异常。这确实是一种安全的烹饪方式。

getIngredients方法处理可用的配料,并返回一个包含配料的数组。它还防止你的披萨在没有辣椒的情况下变得不好吃——它添加番茄作为后备配料。

getToppings方法的功能类似。它提供了一个你想要添加以使你的披萨更美味的配料列表。

在控制器内部,模型的使用就像任何其他类一样。在startCookingAction中,你所做的只是创建一个新的模型对象并从模型中获取值。

更简单!所以,你在 Symfony 中创建了一个新的模型。恭喜!你可以安全地享用你刚刚烤好的披萨(或者烹饪——请注意,你是一名工程师而不是厨师,所以烹饪和烘焙之间的区别不应该让你烦恼)。

使用 Symfony 创建视图

如果你计划使用 Symfony 创建命令行软件,你可以跳过这一部分。但如果你想编写需要展示美丽界面的软件,你需要非常仔细地遵循这一部分。应用程序的面孔被称为视图。

准备工作

如果你坚持默认的 Symfony 设置,你需要在一个特定的目录中创建视图。当前安装中目录的名称是<Project-root>/symfony/src/Acme/DemoBundle/Resources/views。你还必须创建一个包含控制器名称去掉controller单词的目录。因此,当你创建名为CookingController的控制器时,你会创建一个名为Cooking的目录。

如何操作...

在命名文件时,你必须记住,你将使用扩展名.html.twig命名视图文件,文件名将与动作名称相同,去掉Action,这将渲染视图。

所以,你可以有名为index.html.twignameDish.html.twigstartCooking.html.twig的视图,分别对应你创建的indexActionnameDishActionstartCookingAction

到目前为止,你可能想知道TWIG是什么鸟。你也可能正在想开始诅咒作者,因为他提供了如此多的信息。亲爱的,亲爱的,亲爱的。艺术是长久的,生命是短暂的。Twig 是一个用于 PHP 的模板引擎。它被设计用来将动态行为注入 HTML 页面。这对于对服务器端语言知之甚少的用户界面开发者来说特别有帮助,这些语言将 HTML 渲染到网页浏览器上。假设你必须创建一个视图,你将为startCookingAction做如下操作:

<!DOCTYPE html>
<html>
<head>
<title>Let us cook {{ dishname }}</title>
<style type="text/css">
.align-center{
  text-align: center;
}
.heading{
  font-weight: bold;
  font-size: 40px;
}
.normal-text{
  font-size: 16px;
}
</style>
</head>
<body>
<div class="align-center heading">You are now cooking {{ dishname }}!</div>
<div class="align-center normal-text">By adding ingredients
{% for key, ingredient in ingredients %}
| {{ ingredient }}
{% endfor %}
</div>
<div class="align-center normal-text">And toppings
{% for key, topping in toppings %}
| {{ topping }}
{% endfor %}
</div>
</body>
</html>

对你刚才所受的视觉伤害的即时补救措施是向你解释这段代码是如何工作的。这段代码的概述是它是为 HTML 页面而设计的。

它是如何工作的...

在 HTML 的title标签内,有{{ dishname }},这是动态内容。如果你重新访问CookingController中的startCookingAction方法,你会注意到你返回了一个包含dishname索引的数组。占位符dishname从控制器动作中获取其值。如果你控制器返回一个数组,你显然需要迭代整个数组来在视图中使用这些值。for 循环以for开始,以endfor结束。因此,循环遍历控制器返回的数组($ingredients$toppings),数组索引作为键,数组值作为配料和配料分别。因此获得的价值(配料和配料分别)在视图中使用。

你刚刚使用新方法烤了披萨。你喜欢吗?这里没有双关语。

使用 Yii 框架创建模型

路线图从创建模型开始。然后创建控制器并使用你创建的模型。最后,通过创建视图给你的应用程序一个面孔。使用模型获取数据并将其传递到视图中。

如何做到...

创建一个新的模型非常简单。它与在 PhpStorm 中创建一个简单的 PHP 类没有区别。要创建一个新的模型,你需要在<project-root>/app/models中创建一个新的 PHP 类。你的模型看起来可能像以下代码:

namespace app\models;
class Cooking {
  /**
    * Get the ingredients that will be added to your dish
    * @return array Containing the list of ingredients
  */
  public function getIngredients(){
    $ingredients = array('salt','cheese','');
    $ingredientCount = 0;
    try {
      while ($ingredientCount < count($ingredients)) {
        if ($ingredients[$ingredientCount] == '') {
          throw new \ErrorException("\nYou have run out of capsicum.");
        }
        $ingredientCount++;
      }
    } catch (\ErrorException $e) {
      $ingredients[$ingredientCount] = 'tomato';
    }
    return $ingredients;
  }
  public function getToppings(){
    return array('pepperoni','mushroom','onion','spinach');
  }
}

它是如何工作的...

这个模型与你创建的 Symfony 模型完全相同。记得吗?模型的命名空间被声明,以便任何其他类都能访问模型中定义的方法。

可用的异常在ErrorException类中定义,因此用于处理异常。

注意

正是因为他们说你的业务逻辑才是真正重要的。所以,无论框架如何,你的数据类(模型)保持不变。

使用 Yii 框架创建控制器

要创建一个新的控制器,请在控制器文件夹内创建一个新的 PHP 类。命名为CookingController.php。这样做的原因是什么?你现在已经这样做了一段时间了,所以你应该继续这样做,以免你的胃生气。继续烹饪,同志。

如何做到...

要创建一个新的控制器,前往一个新的 PHP 类。使用名称CookingController.php。请记住目录<project-root>/app/controllers。你的控制器看起来可能像以下代码:

namespace app\controllers;

use app\models\Cooking;
use Yii;
use yii\web\Controller;

class CookingController extends Controller
{
  public function actionIndex(){
    $items = new Cooking();
    $dishname = 'pizza';
    $ingredients = $items->getIngredients();
    $toppings = $items->getToppings();
    return $this>render('index',array('dishname'=>$dishname,
    'ingredients'=>$ingredients,'toppings' => $toppings));
  }
}

它是如何工作的...

仔细检查控制器后,你会有复杂的感受。你会在代码中看到一些你熟悉的部分和一些新的元素。

控制器的命名空间声明为app\controllers。这意味着如果其他控制器需要使用在此控制器中定义的方法(动作),那么该控制器将必须使用此命名空间。

由于数据是从你创建的模型中获取的,为了使用模型的方法,你需要使用模型声明的命名空间。

您需要使用定义父控制器(由框架定义)的命名空间。

控制器包含一个名为 actionIndex 的动作。在 Yii 中,定义的动作遵循以下命名约定:以 action 开头,后跟动作的实际目的。因此,actionIndex 将是控制器的默认动作。

动作还需要一个视图。它通过 render 方法调用,第一个参数是视图的名称,另一个参数是从控制器传递到视图的值列表。

使用 Yii 框架创建视图

现在,创建一个视图以使您的应用程序完整。在创建新视图时,您需要小心。

如何做...

视图在项目中的适当位置是 <project-root>/views/<控制器首字母> 目录。因此,您需要在视图下创建一个新目录。创建一个名为 cooking 的新目录。在此目录内,创建一个名为 index.php 的新 PHP 文件。完成这些后,您需要编写一些基本的 HTML 代码来创建视图。您可能会编写如下代码:

<?php
use yii\helpers\Html;
$this->title = 'Let us cook ';
?>
<!DOCTYPE html>
<html >
<head>
<head>
<meta charset="<?= Yii::$app->charset ?>"/>
<title><?= Html::encode($this->title).$dishname ?></title>
<style type="text/css">
.align-center{text-align: center;}
.heading {font-weight: bold;font-size: 40px;}
.normal-text {font-size: 16px;}
</style>
</head>
</head>
<body>

<div class="align-center heading">You are now cooking <?php echo $dishname; ?>!</div>
<div class="align-center normal-text">By adding ingredients
<?php
foreach($ingredients as $ingredient){
  ?> | <?php
  echo $ingredient;
}
?>
</div>
<div class="align-center normal-text">And toppings
<?php
foreach($toppings as $topping){
  ?> | <?php
  echo $topping;
}
?>
</div>
</body>
</html>

它是如何工作的...

代码中的 html 部分是标准的,不使用任何其他框架。CSS 也保持基本,以保持代码可读性和易于理解。当您使用命名空间 YII/helpers/HTML 时,它将 HTML 辅助类置于您的控制之下,该类执行基本的 HTML 操作,例如将可能包含特殊字符的输入编码为 HTML 实体等。框架设置网页上使用的字符集(字符集)。

您从控制器传递的数据现在在您的视图中可用。变量的名称是您传递的数组索引的名称,变量的值是在该数组索引处设置的数组值。因此,您将在视图中拥有 $dishname$ingredients$toppings。为了显示数组的内容,您只需要进行简单的 PHP foreach 循环来遍历数组,您的烹饪过程将完成。

小贴士

不仅 foreach 可以做到这一点——您可以使用您喜欢的任何循环控制结构。

使用 Zend 框架创建模型

您将需要一个新模型来使所有配料和配料可用。然后,您需要一个控制器,它将是您应用程序的入口点,并控制烹饪过程。为了总结,您需要一个视图,您将从中传递控制器中的数据,您的烹饪过程将结束。

如何做...

这次,创建新模型一点也不难。

您只需在 <project-root>/module/Application/src/Application/Model 目录中创建一个新的 PHP 类,就像您一直做的那样。

命名为 Cooking,并将命名空间设置为 Application\Model。您的模型类的目的是提供配料以方便烹饪过程。

你的模型将类似于以下代码:

namespace Application\Model;
class Cooking {
  /**
    * Get the ingredients that will be added to your dish
    * @return array Containing the list of ingredients
  */
  public function getIngredients(){
    $ingredients = array( 'salt','cheese', '' );

    $ingredientCount = 0;
    try {
      while ($ingredientCount < count($ingredients)) {
        if ($ingredients[$ingredientCount] == '') {
          throw new \ErrorException("\nYou have run out of capsicum.");
        }
        $ingredientCount++;
      }
    } catch (\ErrorException $e) {
      $ingredients[$ingredientCount] = 'tomato';
    }
    return $ingredients;
  }
  public function getToppings(){
    return array( 'pepperoni', 'mushroom', 'onion', 'spinach' );
  }
}

它是如何工作的...

模型很容易理解,因为如果你足够细心并且有合理的记忆力,你将很容易回忆起模型确实是相同的。这里唯一的区别是异常处理类。Zend 提供了 ErrorException 来处理常见的异常。

到现在为止,因为你很容易就创建了一个模型,你应该感觉好多了。

使用 Zend 框架创建控制器

现在是时候创建一个新的控制器了。为此,你必须执行以下步骤:

  1. <project root>/module/Application/src/Application/Controller 中创建一个新的类。

  2. 命名为 CookingController,并设置名字空间 Application\Controller

  3. 由于你需要在代码中使用模型的方法,所以使用模型的名字空间。

  4. 由于你需要告诉 Zend 你的控制器是 AbstractActionController,所以使用 AbstractActionController 的名字空间。

  5. 使用 ViewModel 的名字空间,因为当你运行代码时,你需要渲染一个视图。你的控制器将类似于以下代码:

    namespace Application\Controller;
    
    use Application\Model\Cooking;
    use Zend\Mvc\Controller\AbstractActionController;
    use Zend\View\Model\ViewModel;
    class CookingController extends AbstractActionController {
      public function indexAction() {
        $dishname = 'Pizza';
        $items = new Cooking();
        $renderView = new ViewModel(
          array('dishname' => $dishname,'ingredients' => $items->getIngredients(),
        'toppings' => $items->getToppings()));
        $renderView->setTerminal(true);
        return $renderView;
      }
    }
    

它是如何工作的...

你刚才编写的代码是一个控制器类,它使用其他一些类来按照你的要求使事情正常工作。因此,你可能已经注意到的典型事情是 ViewModel 方法。实际上,ViewModel 方法是定义在 Zend\View\Model\ViewModel 命名空间中的 ViewModel 类的构造方法。这个方法的目的在于渲染视图,并在必要时从控制器传递一些值。属于 ViewModel 类的 setTerminal 方法防止在视图中渲染任何其他布局。如果没有这个方法,框架会在某个地方寻找 layout.phtml 文件,这将渲染视图组件的一般布局。因此,你的整个展示将位于你将要创建的 index.phtml 文件中。

使用 Zend 框架创建视图

在创建了控制器和模型之后,你可以继续创建视图,给你的应用程序一个外观。

如何做到这一点...

  1. 进入 <project-root>/module/Application/view/application/cooking 目录,创建一个新的 PHP 文件,并将其命名为 index.phtml

    Phtml 是在 Zend 框架中使用的特殊扩展名,它告诉 web 服务器文件中预期的内容将是更多 HTML 而不是 PHP。

    换句话说,这是一种告诉服务器该文件是一个视图组件的方式。就像你一直这样做来创建视图一样,这次你也将采取类似的行动。毕竟,视图就是视图。

  2. 你将创建类似于以下代码的内容:

    <?php echo $this->doctype(); ?>
    <html lang="en">
    <head>
    <?php echo $this->headTitle('Let us cook '.$dishname)->setSeparator(' - ')->setAutoEscape(false) ?>
    </head>
    

    现在我们已经定义了标题。让我们转到代码的其他部分,如下所示:

    <style type="text/css">
    .align-center{ text-align: center; }
    .heading{ font-weight: bold; font-size: 40px; }
    .normal-text{ font-size: 16px; }
    </style>
    
  3. 以下是一段简单易懂的 CSS 代码,用于装饰食谱:

    <body>
    <div class="align-center heading">You are now cooking <?php echo $dishname; ?>!</div>
    <div class="align-center normal-text">By adding ingredients
    <?php
    foreach($ingredients as $ingredient){
      ?> | <?php
      echo $ingredient;
    }?>
    </div>
    <div class="align-center normal-text">and toppings
    <?php
    foreach($toppings as $topping){
      ?> | <?php
      echo $topping;
    }?>
    </div>
    </body>
    </html>
    

它是如何工作的...

HTML 部分相当简单。区别在于以下两点:

  • $this->doctype(): 这是 Zend\View\Renderer\PhpRenderer 类中的一个方法,用于设置 HTML 页面的 doctype 声明。

  • $this->headTitle($title): 这是同一类中的一个方法,用于将页面的标题设置为 $title。在用法方面,剩余部分完全相同。

详细信息!雷鸣!您的披萨仍然没有做好。您需要在 Zend 框架中做更多的工作。现在是时候转到 还有更多… 部分来烘烤您的不完整的披萨了。

还有更多...

您需要创建与您的应用程序模块相关的配置。在 <Project-root>/module/Application/config 目录下,创建一个名为 module.config.php 的新 PHP 文件。您需要告诉 Zend 框架您将用于制作披萨的路由、控制器和视图。

您的努力可以呈现以下形式:

return array('router' => array('routes' => array('home' => array('type' =>'Zend\Mvc\Router\Http\Literal', 'options' => array('route' => '/', 'defaults' => array('controller' => 'Application\Controller\Cooking', 'action' => 'index', ),),),),),
'controllers' => array( 'invokables' => array( 'Application\Controller\Cooking' =>'Application\Controller\CookingController'),),
'view_manager' => array( 'template_path_stack' => array( __DIR__ . '/../view',),),);

路由器包含路由。路由包含主页路由。主页路由包含路由类型和路由选项。路由选项包含路由和默认值,例如控制器名称和动作名称。因此,您希望您的 CookingController 默认激活,并且 indexAction 默认执行。

控制器包含您希望 Zend 通过其名称识别的名称。实际上,Zend 通过去除 Controller 单词来记住您的控制器名称。因此,Zend 将通过您指定的不可侵犯的设置来调用您的控制器。控制器包含您希望 Zend 通过其名称识别的名称。实际上,Zend 通过去除 Controller 单词来记住您的控制器名称。因此,Zend 将通过您指定的不可侵犯的设置来调用您的控制器。控制器包含您希望 Zend 通过其名称识别的名称。实际上,Zend 通过去除 Controller 单词来记住您的控制器名称。因此,Zend 将通过您指定的不可侵犯的设置来调用您的控制器。

创建了视图后,您将想要告诉 Zend 您的视图文件在哪里。在内部,view_manager 通过设置模板路径(template_path_stack)来完成同样的工作。

仍然还有一些工作要做。哦,上帝!披萨什么时候能做好?上帝说:“要有耐心,要诚实。你会享受的。”

您必须在 <Project-root>/module/Application 目录下创建一个新的 PHP 类(命名为 Module),这样您才能使用您模块的路由和相关设置。您的 Module.php 文件将看起来像以下代码:

namespace Application;
class Module {
  public function getConfig(){
  return include __DIR__ . '/config/module.config.php';
}

public function getAutoloaderConfig() {
  return array(
    'Zend\Loader\StandardAutoloader' => array(
      'namespaces' => array(
      __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),),);
  }
}

您需要坚持使用 Zend 系统,以确保事情正确且标准化。要使用特定模块的配置,您需要在 getConfig 方法内部使用设置。为了告诉 Zend 执行时需要包含的类,您需要使用 getAutoloaderConfig

现在,您可以宣称您已经成功制作了披萨。您现在可以坐回沙发上,享受美味。如果您不太喜欢这个味道,总有下一次的机会!

第五章:测试和调试

在本章中,我们将涵盖以下主题:

  • 安装 PHPUnit

  • PHPUnit 中的测试用例

  • 使用 PHPUnit 测试应用程序

  • 开始调试会话

  • 设置断点

  • 配置断点条件

  • 创建异常断点

  • 步进你的代码

  • 运行到选定的代码行

  • 观察表达式和变量

  • 评估表达式

  • 在线更改代码

  • PhpStorm 中的代码覆盖率

简介

每当你创建一个新的软件时,都会在它上面固有一个业务依赖。显然,如果你的软件没有出售,你可能已经选择了其他职业。由于业务因素,你总是期望你的软件是可靠的。这只能在软件通过测试后才能实现。并不是说,程序员们将做所有的测试并将测试人员踢出去。你需要在编写代码的同时进行单元测试。如果你对你的代码进行单元测试,失败的可能性会大大降低。理想情况下,单元测试应该在创建代码时进行,而进行单元测试的理想时间是在某个里程碑功能创建后立即进行。

要明智行事并进行(单元)测试,请使用 PHPUnit。PHPUnit是一个用你最喜欢的 PHP 编写的系统(应用程序)。它让你为编写的代码编写测试用例,这样你就可以继续检查任何可能潜入你逻辑中的错误。因此,在你使用构建工具创建类似 phar 或其他存档时,你已经确保了已经应用了第一层过滤。

显然,你会问 PHPUnit 的用途。这个答案很简单:你需要 PHPUnit 来防止错误传递到集成测试阶段。但如果在单元测试阶段有一些错误或功能无法检测到怎么办?如果由于另一个组件或模块传递了错误数据而出现错误怎么办?

不要将改变一个人存在的时态的规则应用到测试用例上,你再次被建议要明智行事。使用调试器。大多数 IDEs 都会在调试器旁边显示一个带有 bug 图标的调试器,所以你不会在 PhpStorm 中很难找到它。PhpStorm 为你提供了选择调试器并集成以供使用的选项。

使用调试器,你可以创造奇迹。你实际上可以对你的代码获得细粒度的控制。你获得了穿越墙壁和透视铁板的权力!请停止梦想成为超级英雄,你仍然是一名软件工程师?调试器给你提供了查看代码中任何变量的值和方法返回值的能力,可以随意暂停执行并随意恢复,而且列表无穷无尽。

在深入知识海洋之前,了解测试和调试之间的区别很重要。测试是一个可能在开发阶段进行的过程,在开发了一些业务逻辑之后,它需要在发布到生产之前被彻底清理和净化。调试是从代码中移除错误的过程。错误是那些在测试阶段通过且在后续测试阶段或甚至在生产阶段被发现的不希望(不适当)的功能。实际上,两者是相似的,因为它们的目的只是清理产品和功能软件应用。

安装 PHPUnit

讨论从测试开始,因为在软件开发生命周期中,测试发生在调试之前。PHP 提供了一个单元测试系统,称为 PHPUnit。

准备工作

如果你使用 PHPUnit,你将获得编写一些代码和检查一些代码的自由。是的,你没听错。你可以使用 PHPUnit 编写一些程序来检查其他程序输入和输出。有趣的现象,对吧?

当你可以使用一个应用程序(PhpStorm)编写一个应用程序(PHP 代码)时,为什么不使用一个应用程序(PHPUnit 测试用例)来测试这个应用程序(PHP 代码)呢?由于 PHPUnit 只是一个用 PHP 编写的应用程序,它以PHP 归档PHAR)的形式提供。它只是将你的文件和文件夹作为一个整体发送并使其准备就绪以执行的方法。

注意

在安装 PHPUnit 之前,请确保你已经安装了 PHP 解释器。

如何做...

你可以通过下载 PHPUnit 归档(PHAR 文件)并在包含路径列表中将 /path/to/phpunit.phar 设置为非常容易地安装它。

你只需要执行以下步骤:

  1. 前往项目视图。

  2. 外部库目录上右键单击以访问上下文菜单。

  3. 选择配置 PHP 包含路径选项。

你也可以通过选择外部库目录,按 F4,并指向正确的 phpunit.phar 文件来快速完成,如下面的截图所示:

如何做...

它是如何工作的...

由于你已经将 PHPUnit 作为包(PHAR)安装,测试系统将在你继承(或扩展)位于 phpunit 目录下 phpunit-lts.phar 目录和名为 PHPUnit_Framework_TestCase 的框架子目录中的类时立即启动。

PHPUnit 中的测试用例

成功安装 PHPUnit 后,你的挑战还没有结束——它只是引出了一系列新的挑战。测试不是一件容易的事情,但它很有趣。就像你喜欢编写漂亮的 PHP 代码一样,你也会喜欢在 PHPUnit 中编写测试用例,因为它就像编写 PHP 代码的同时注意一些约定。

测试用例是一段专门编写来检查(或测试)另一个应用程序中某些条件的应用程序代码的一部分。因此,当你编写测试用例时,你实际上是在编写 PHP 代码来测试其他 PHP 代码(即你编写的满足业务需求的代码)中是否出现了错误。

在这里,很重要的一点是指出,作为程序员,你通常有以下观点:

  • 你认为既然你非常了解你的代码,你就知道你的代码没有错误

  • 即使你的代码中存在一些错误,由于你对代码了解得很深,你可以迅速修复它们

  • 你认为你在编写测试用例上浪费的时间可以更好地用于编写更多的代码

这些(以及许多类似)点是错误的。你需要编写测试用例。

如何操作...

要创建一个新的测试用例,你需要创建一个新的 PHPUnit 类。因此,执行以下步骤:

  1. 转到项目视图。

  2. 选择你想要测试的文件。这个文件应该是一个有效的 PHP 类。这是一个明显的陈述。

  3. 从右键单击上下文菜单中选择新建 | PHPUnit | PHPUnit 测试用例,如图所示:如何操作...

  4. 提供名称和相关细节,就像你创建新的 PHP 类时做的那样。

注意

你创建的测试用例将是这个类中具有公共访问修饰符的 PHP 方法。

它是如何工作的...

要查看测试用例的工作原理,你需要遵循一些约定。原因是,由于测试用例是 PHP 代码,它必须具有一些固有的功能。以下列出了这些约定,以便快速参考:

  • 测试类应该与目标类具有相同的名称。因此,在XXXTest.php文件中创建XXXTest,假设要测试的类名为XXX

  • 所有测试类都应该扩展(继承)PHPUnit_Framework_TestCase类。当你将 PHAR 包含到你的 PhpStorm 项目中时,这个类就对你可用(正如我们在本章的安装 PHPUnit小节中看到的)。

因此,你的XXXTest类将具有以下声明:

class XXXTest extends PHPUnit_Framework_TestCase{
..
}

测试类中要测试的确切方法应该以test开头,后跟要测试的方法名。

并非你的测试仅仅因为这个原因就会失败,但这是一种标准的命名约定。

没有任何约束要求你将一对一的测试方法映射到单个目标方法。这同样只是一种良好的实践。

因此,考虑到要测试的方法名为YYY,你的测试类中的测试将具有以下声明(定义):

public function testYYY(){
  ...
}

根据约定,你应该在单个方法中编写一个测试。这有助于更好地组织代码,并使其更容易理解。

实际的测试是通过断言一些事实来完成的。这些事实是你将要测试的方法的输出。因此,如果某个方法返回一个字符串,你可以通过编写以下代码行来检查该方法返回类型是否为string

   $this->assertInternalType("string", $methodReturnValue);

测试类应该在setUp方法内部包含常见内容。这在需要在这个类的所有测试方法中共享一段代码的情况下特别有用。是否使用它由你决定。

在被调用的测试方法结束时,你可能不需要保留资源。你可能想要将其从内存中删除。

在这里,记住这一点非常重要,你应该始终明智地设计你的测试。你应该始终防止在测试中产生不必要的内存使用,因为一旦你做到了这一点,你将不得不在这个测试类上添加另一个测试。

了解了测试用例的细微差别,你现在已经准备好进行测试了。这是故意滥用字母表中的字母来提醒你!

无论你做什么,PhpStorm 都会帮助你。所以,不要等待和思考要做什么,准备就绪,出发吧!

使用 PHPUnit 测试应用程序

你心中可能有一个关于 PhpStorm 在这个测试中作用的问题。现在是采取行动的时候了。有了足够的关于编写测试的规范知识,你可以进入测试的真正世界。你测试得越多,你的代码就会越纯净。测试是好的。测试是健康的。测试是推荐的。

如何做...

好问题。这个问题最好通过回到过去,回到相同的比萨饼烹饪用例来回答。你从小就听着奶奶的建议去重复使用物品。现在是你重复使用的时候了。执行以下步骤:

  1. 重复使用PizzaDish类。你将创建一个类似于以下测试类:

    require_once "PizzaDish.php";
    class PizzaDishTest extends PHPUnit_Framework_TestCase {
    
      function setUp(){
        $this->pizzaDish = new PizzaDish("Pizza Dish", "Dish");
      }
    
      function tearDown(){
        unset($this->pizzaDish);
      }
    
      public function testGetInstance(){
        $this->assertInstanceOf('Dish',
        $this->pizzaDish->getInstance());
      }
    
      public function testGetDishName(){
        $this->assertInternalType("string", 
        $this->pizzaDish->getDishName());
      }
    }
    

    正如承诺的那样,你可以看到 PHPUnit 完全是关于编写 PHP 类。

  2. 要执行这个测试,你需要运行(执行)这个类。

  3. 运行这个类非常简单。Ctrl + Shift + F10是你的救星。

  4. 如果你只想运行一个方法,PhpStorm 也为此提供了支持。你只需将光标放在你想要执行的方法体内任何位置,然后发出运行命令。

    小贴士

    如果光标不在方法体内,整个测试类将被执行。

以下截图显示了测试结果:

如何做...

它是如何工作的...

为了执行你的单元测试,PhpStorm 进行了一些改进。就像它对其他每个库所做的那样,它使用自己的执行脚本来执行测试。该文件的完整名称是/tmp/ide-phpunit.php。因此,正是这个文件接受你编写的测试类文件的名称。

测试应用程序的工作原理很简单。正如已经提到的,所有继承自PHPUnit_Framework_TestCase类的类都成为测试类。setUp方法实例化目标类PizzaDish的对象,并将其提供给整个测试类。

在你的测试类内部,当你运行测试时,testGetInstancetestGetDishName方法会被执行。在测试方法内部,会实例化一个新的对象以启动实际的测试过程。直到这一点,你所做的活动与 PHP 类的活动相同。在方法内部,有一些断言执行实际的测试。有这些特殊的方法,即assertInstanceOfassertInternalType,这些方法是在框架提供的Assert类中声明的。你可以通过将光标放在方法名下并按Ctrl + Q来查看该方法的文档。这些是实际通过检查给定的断言是否为真来执行测试任务的方法。因此,你创建的测试类的目的是检查是否实例化了所需的类,以及你想要烹饪的菜名是否为string类型。

注意

一旦运行测试,你将能够在通常的运行视图中看到测试结果,该视图可以通过Alt + 4访问。

开始调试会话

"现在是所有程序员开始调试他们的代码的时候了"

与大多数 IDE 一样,PhpStorm 也使用一个错误图标来显示调试器。就像虫子吸血并让你无法专注于主要任务一样,软件错误可以消耗宝贵的 CPU 周期,并阻止你的软件按预期工作。

为了防止此类错误进入软件的生命周期,你需要进行调试。调试是一个深入代码的过程,找出可能成为代码中问题区域的潜在区域,因此需要进行广泛的查找以发现和修复错误。

用于此目的的工具在业界被称为调试器。Xdebug是此类工具的名称。它是一个非常常用、免费且开源的调试器,可以与大多数 IDE 连接。

准备工作

要连接它,你需要在你的开发机器上安装它。执行以下步骤:

  1. GitHub检出源代码,这是 Xdebug 托管的地方。你需要在终端中发出此命令git clone git://github.com/xdebug/xdebug.git

  2. 进入已检出代码的目录。

  3. 发出phpize命令。当你这样做时,控制台将输出大量文本。一旦输出完成,你需要执行配置文件,它恰好是一个可执行的 shell 脚本。

  4. 在配置时,你需要使用--enable-xdebug开关启用xdebug。因此,你应该写./configure --enable-xdebug

  5. 完成这些后,你需要发出make && make install命令以完成编译。

  6. 步骤的输出将是一个模块——确切地说是一个共享对象或 .so 文件,您需要在 PHP 设置中指定它。请记住这一点。

  7. 在适当的 ini 文件中,您需要写下以下代码:

    zend_extension="/path/to/compiled/xdebug/so/xdebug.so" 
    xdebug.remote_enable=On
    xdebug.remote_host=localhost
    xdebug.remote_port=9000
    
  8. 为了知道您的 PhpStorm 使用哪个 php.ini 文件,您需要转到 工具 | 运行命令 并执行命令 php --ini。您将获得所有解析的 .ini 文件列表。现在您有了正确的 .ini 文件来做出更改。

    注意

    此外,还有一个快捷键,Ctrl + Shift + X,它打开命令行工具控制台。

安装了强大的调试器后,您可以继续使您的代码无错误。

如何做到这一点...

仅针对基于 Web 的 PHP 应用程序启动调试会话。为了能够启动 Web 应用的调试,请执行以下步骤:

  1. 您需要有一个,比如说 Chrome 的 xdebug 辅助工具。它帮助您在输入 URL 后启动调试会话。

  2. 您知道,对于客户端,应该有一个服务器,这样当您尝试启动调试会话时,必须有监听传入连接的监听器。

  3. 因此,您需要启动传入调试连接的监听器。为此,您需要转到 运行 | 开始监听调试连接

  4. 第一次启动会话后,PhpStorm 会显示有关某些条目的警报,如下一个信息框后的截图所示:

    注意

    确保已勾选 可以接受外部连接 的复选框。这可以在 设置 | PHP | 调试 中找到。

    如何做到这一点...

如何工作...

一旦您接受连接,PhpStorm 会将其保存。已保存的服务器可以在 文件 | 设置 | PHP | 服务器 下稍后查看。从这一点开始,基于 Web 的应用程序和命令行应用程序的调试过程将相同。因此,调试器将查看代码中的任何变量,并根据您提供的断点,暂停、继续、逐行或跳过代码,从而使您能够非常容易地看到代码内部正在发生什么。

小贴士

您也可以访问 www.xdebug.org/wizard.php 了解更多关于您服务器上 xdebug 安装的详细信息。

设置断点

代码中的断点是指您希望程序执行暂停的(或代码行)。当您在烤披萨并添加配料时,假设您想知道在任何时刻即将添加哪种配料,您可以设置一个断点,使解释器暂停在包含即将添加的配料名称的变量的那一行。设置断点后,您可以在调试窗口的变量框架中看到变量的值。

断点有两种类型,如下所示:

  • 永久断点:一个常规断点是指它将一直存在,直到您手动移除它

  • 临时断点:另一方面,临时断点是在满足某些条件时被移除或禁用的断点,最常见的条件是触发。

如何操作...

  1. 要设置一个常规断点,您需要通过将光标放在可疑代码行下选择该行代码。

  2. 前往运行 | 切换行断点

  3. 在左侧面板上将会创建一个红色圆圈,以提供视觉指示,表明该行是一个断点。

  4. 您可以使用键盘快捷键 Ctrl + F8 做同样的事情。

如何工作...

断点允许您查看变量栈的状态。因此,当解释器在断点处停止时,您可以查看程序执行中涉及的变量的内容。如果您添加了一些变量或表达式到监视中,您可以在当前作用域内始终查看所选变量的内容,只要它保持在该作用域内。在执行的其他所有时间,都会显示消息无法评估表达式。调试器向解释器提供指令,在断点被触发时暂停执行。根据请求,调试器指示解释器将(输出)消息写入控制台(对人类眼睛来说,这看起来像是 PhpStorm 完成了这项工作!)

配置断点条件

PhpStorm 提供了自定义断点的方法。因此,您有更多的舒适度来坐下来享受调试过程,同时确保您的任务能够按时完成。

如何操作...

  1. 一旦您设置了断点,您可以按 Ctrl + Shift + F8 来获取一个配置面板。使用该面板,您可以将常规断点更改为临时断点。

  2. 勾选一旦触发则移除选项旁边的复选框。这样,该断点只会在断点被触发一次后存在。

  3. 您可以选择将消息记录到控制台,以便在断点被触发时输出。

  4. 您可以通过勾选记录评估表达式复选框来创建一个表达式,一旦这个断点被触发就会进行评估。您也可以有条件地使这个断点保持休眠状态。

  5. 您可以告诉 PhpStorm 激活此断点,使其保持禁用状态,直到抛出特定类型的异常,如以下截图所示:如何操作...

如何工作...

再次强调,关于断点是如何工作的,并没有逻辑上的解释。您需要遵循显示的步骤,PhpStorm 会为您完成这项工作。其工作原理与操作系统有关。

小贴士

在弹出窗口仍然打开时,您可以按 Ctrl + Shift + F8 来获取一个更大的面板,您可以在其中查看代码,同时仍然保持控制面板打开。

如以下截图所示:

如何工作...

创建异常断点

您的大脑需要吸收新的信息。直到这个时间点,您都认为只有在怀疑某些代码行可能有问题时,才能手动创建断点。但实际上,您可以在遇到异常时创建一个断点。这种类型的断点被称为异常断点。您可能会想,“为什么会有这个名字?”这个断点在遇到异常时被激活。

如何操作...

要创建一个新的异常断点,您只需记住几个小步骤:

  1. 在编辑器内部,按Ctrl + Shift + F8,那里将弹出一个窗口。

  2. 在左上角,有一个+号,按它,您将获得创建异常断点的选项。

  3. 在继续之前,您将被要求输入希望执行停止的异常名称。

  4. 您还可以自定义断点行为的方式。您可以要求 PhpStorm 在代码中抛出意外(或未捕获)异常时激活此断点,如下面的截图所示。这对于明智的程序员来说特别有帮助,因为大多数预期的异常已经包含在代码中。除了这个不同之处外,适用于一般断点的所有其他规则也适用于异常断点。如何操作...

    注意

    一旦触发,您就不能禁用异常断点。换句话说,您不能创建一个临时的异常断点。

  5. 如果您希望异常断点在某些条件下被激活,您可以暂时禁用异常,直到另一个异常发生或另一个断点被触发。PhpStorm 为您提供了从断点列表中选择选项的功能。

    小贴士

    为了避免在决定选择哪个异常时费尽心思,您可以选择将异常设置为Exception类。这可能会很有用,因为所有异常类最终都继承了这个Exception类。

它是如何工作的...

执行将继续以正常方式进行——如果您设置了断点,将会有暂停,就像以前一样。但现在,执行将在异常发生时暂停。因此,这个异常断点是一个不可见的断点,您将看不到它,但内部它将是活跃的。作为一个断点,它将继续像断点一样工作。

逐步执行您的代码

生活时刻都在教导我们新的课程。对于所有那些发现短语“逐步执行代码”是新的你们来说,这是一个分析变量值、控制结构和方法调用层次的过程。这个过程包括三种类型的逐步执行:

  • 进入

  • 跳过

  • 跳出

准备工作

你真的需要逐步执行代码吗?当然需要。什么时候?当你需要找出代码中的瑕疵时。当你需要知道整个程序中的下一行时,你必须进入代码。当你需要知道整个程序中的下一行将要执行时,你必须跳过代码。当你需要知道所选方法之后的下一行时,你必须从代码中退出。

如何操作...

为了逐步执行代码,你只需处于调试会话中。其余的只是点击或键盘快捷键的事。执行以下步骤:

  1. 从逐步执行代码开始。当你的调试会话处于活动状态时,你需要按F8或选择以下截图所示的按钮:如何操作...

  2. 为了进入代码,你只需按F7或选择以下截图所示的按钮:如何操作...

  3. 为了从代码中退出,你需要使用键盘组合Shift + F8或选择以下截图所示的按钮:如何操作...

它是如何工作的...

一旦你使用了任何逐步执行的方法,你显然会想知道幕后发生了什么。一个非常高级的解释会告诉你,当你进入代码时,调试器会带你到程序中的下一行。一旦你在代码的下一行,你可以在该代码行上执行很多检查,例如变量的内容。

一旦你进入代码,调试器实际上会显示在同一程序文件或另一个程序文件中立即执行的下一行。一旦显示,你可以在该代码行上再次执行很多检查。

一旦你从代码中退出,调试器会显示在当前方法执行之后将立即执行的下一行。如果调试器无法找到这样的行,执行将以通常的方式完成,就像没有调试器一样。

注意

在尝试F8F7Shift + F8等快捷键之前,你必须有一个调试会话。

跳转到选定的代码行

如果你不想在代码中设置断点,但仍然希望调试器在代码的某个点中断,你找到了正确的配方,正在阅读正确的文本。这也适用于你设置的断点已经执行或跳过,但你仍然怀疑另一行有错误。

如何操作...

  1. 要让 PhpStorm 告诉调试器在某个你选择的任意点中断,你应该使用 运行到光标处 选项。作为先决条件,你必须将光标放在程序中的某一行代码上。完成这个步骤后,你现在需要转到 运行 | 运行到光标处,PhpStorm 将会顺从地(并且礼貌地)请求 Xdebug 在光标所在的位置暂停。这和常规断点的情况是一样的行为。

  2. 有三种情况需要考虑:

    • 第一种情况是你刚开始调试代码;执行将在你指定的行上暂停。

    • 另一个情况是当你已经在代码中指定了一个断点,并且调试器已经超过该断点(显然是在暂停之后),调试器将再次在指定的行上停止。

    • 第三种情况是当你指定了一行根本不会执行的代码——如果你有辣椒,你不会加番茄。在这种情况下,执行将继续到那一行之后,并移动到下一个断点或完全结束。

    如何操作...

它是如何工作的...

魔法的运作原理非常简单易懂。就像临时断点一旦触发就会消失一样,这个 运行到光标处 选项也是以同样的方式工作的。因此,你放置光标的代码行变成一个临时断点,具有额外的不可见特性。因此,一旦断点被触发一次,它就会自动无痕地移除。如果有一行永远不会被执行,调试器将简单地忽略代码中的这个位置并继续前进。

注意

键盘快捷键可以提升你的速度。使用 Alt + F9 来快速操作。

观察表达式和变量

调试器的最重要的功能是它实际上为你提供了 X 光眼镜,让你可以看穿不透明物体。

这种看穿不透明物体(称为执行)的现象被称为 监视。它与现实世界的监视是同义的。你监视某物吗?你不断地关注你所监视的周围发生的事情。爸爸说,“我会看到你,儿子”,无论地点如何,儿子担忧的问题就会出现。但是,PhpStorm 的监视功能会让你担忧吗?

如何操作...

如果你决心要观察一个变量的位置和活动情况,你可以让 PhpStorm 帮你完成。当你开始调试时,在调试窗口中,默认打开三个框架:框架变量监视。要将变量添加到监视功能中,有两种方法:

  • 如果那个变量出现在到那个点为止被覆盖的变量列表中,你可以选择该变量,访问右键点击的上下文菜单,从列表中选择 添加到监视 选项。你会看到监视部分将添加一个变量,就像这个一样。

  • 如果该变量未出现在变量列表中,您无需担心。如果您记得您怀疑的变量名,您可以直接在监视变量列表(在监视窗口中)下添加它,通过选择+符号并在出现的文本框中输入变量的确切名称,如图所示:如何操作...

PhpStorm 还允许您以与变量相同的方式添加监视表达式。您只需像在编辑器内部编写一样编写一个表达式即可。PhpStorm 会处理其余部分。

它是如何工作的...

当一个变量被置于监视之下时,PhpStorm 会简单地将其内容输出到控制台,这恰好是一个监视窗口。因此,被监视的变量在程序执行(调试)的整个过程中始终保持可见。如果变量值发生变化,变化将立即反映在监视窗口中。如果在执行过程中变量超出了作用域,变量的内容将变为无法评估表达式。因此,您可能会觉得内容不可用,尽管实际上内容是可用的。

对于表达式也是如此。IDE 将其视为正常内容,并尝试始终显示其值。就像在监视正常变量的情况下发生的那样,如果表达式包含当前作用域中未覆盖的变量,表达式将评估为无法评估表达式

小贴士

请务必记住使用变量的确切名称。

飞行中更改代码

根据没有调查,已经确定大多数编程错误是由于数据类型和值的不确定性引起的。调试器的真正效用在于您在执行过程中可以自由地干预生成的数据。因此,您实际上可以更改解释器在您与代码中的错误作斗争时覆盖的变量的值。

这在您必须设置文本容器的宽度,但又无法确定文本容器的最大宽度的情况下尤其有用。

如何操作...

  1. 在此场景中,调试视图是您的朋友。关注变量框架。

  2. 要给变量赋值,从可用的变量列表中选择它。

  3. 访问右键单击上下文菜单。选择设置值选项,并在出现的文本框中提供一些值。按下回车键后,您立即完成。

  4. 从现在开始,无论何时访问这个变量,它都将假定这个特定的值。执行此操作的快捷键由 PhpStorm 提供,即F2

它是如何工作的...

到目前为止,您肯定已经轻松猜到调试器位于您的代码和解释器之间。因此,当您给一个变量赋值时,调试器通过传递更改后的值作为原始值来“欺骗”解释器。解释器,一个可怜的盲生物,通过假设值是代码中指定的值,并使用这个值继续前进,而陷入了这种困境。

世界根本不被信任!

注意

当您给一个变量赋值时,并不意味着值将固定,而不考虑业务逻辑。一旦满足变量将更改其值的条件,变化就会像没有调试器时一样正常发生。

PhpStorm 中的代码覆盖率

在将平台设置为编写干净代码并从代码中移除错误以制作好软件之后,您肯定在想,您的任务已经完成,现在您可以坐下来放松了。

现在还不是时候!还有更多的事情要做。既然您承诺您不会感到疲倦,您不会失败,您内心必须燃烧着继续前进的火焰。这次,您将进行代码覆盖率。是的,您没有看错,代码覆盖率。

现在您已经对测试系统(PHPUnit)和调试系统(Xdebug)有了实际的知识,这是了解这种现象的合适时机。代码覆盖率是由 PHPUnit 和 Xdebug 提供的联合功能带来的现象。这意味着,如果您真的想要代码覆盖率,您必须在您的开发机器上安装这两个系统。

准备工作

为了解决这些事情,出现了代码覆盖率。不,不,不要认为代码覆盖率会移除未使用的行——将是你移除它们。覆盖率会告诉你从哪里移除未使用的行。因此,代码覆盖率是一种检查在执行过程中哪些代码行被覆盖,哪些代码行没有被覆盖的现象。您内心充满了疑问——那么 PhpStorm 在这个问题中扮演什么角色呢?当您进行代码覆盖率时,您会得到一个视觉指示,告诉您哪些行没有被覆盖。正是这个 PhpStorm 功能负责管理这种视觉指示给您。

如何操作...

再次覆盖 PHP 代码需要一些 PHP 代码。您必须编写世界上的一切!编写测试的简单方法是为目标类编写测试。框架(PHPUnit)将尝试覆盖整个类。在这种情况下,您在编写代码时不需要做任何新的工作,因为变化发生在您尝试运行测试时。

PhpStorm 中有一个选项可以让您运行带有覆盖率测试。为此,您需要执行以下步骤:

  1. 您需要选择测试文件并转到运行 | 运行 <test> 带有覆盖率,如图下所示截图。

  2. 目标文件将以常规方式测试,并且整个文件的覆盖率也将得到处理。如何操作...

  3. 然而,假设你想覆盖代码的一部分或一个方法,你也可以做到。PHPUnit 提供了一个名为covers的注释。使用这个注释,你可以告诉 PHP 解释器你只想覆盖目标类中的选定部分。

  4. 因此,如果你只想测试(target) PizzaDish类中的getDishName方法,你可以在PizzaDishTest类中testGetDishName方法声明之前使用如下代码:

    /**
      * @covers PizzaDish::getDishName
    */
    public function testGetDishName(){
      $this->assertInternalType("string",
      $this->pizzaDish->getDishName());
    }
    
  5. 在你的编程生涯中,会有一些时候你不想做任何有趣的事情。你只是想测试代码,而不覆盖任何代码——你只想测试。你有选择。有一个名为coversNothing的注释可用。这是告诉 PHPUnit 框架“好的,伙计,你只会为我进行测试。不要浪费时间在覆盖代码上。”的一种方式。因此,你可以编写如下代码:

    /**
      * @coversNothing
    */
    public function testGetInstance(){
      $this->assertInstanceOf('Dish', $this->pizzaDish- >getInstance());
    }
    

使用了注释后,你成功操作了代码覆盖率的功能。恭喜你!

如何工作...

注释是 PHP 中的特殊功能,为解释器提供一些信息以执行某些工作而不发出声音。因此,当你写下@covers <Classname>::<Method-name>时,你是在告诉解释器覆盖目标类中的某些代码。同样,当你写下@coversNothing时,解释器理解它不需要进行覆盖率。

因此,PhpStorm 通过用特定颜色给你的代码区域着色来提供视觉指示,表示覆盖率和不覆盖。当你运行带有覆盖率的测试时,编辑器窗口的右下角会显示覆盖率视图,如下面的截图所示。你可以查看刚刚测试过的代码的统计数据(包括覆盖率)。

如何工作...

你也会得到视觉指示。它显示在目标类的编辑器窗口中(这里为PizzaDish.php,如下面的截图所示),红色区域表示未覆盖。

如何工作...

更多内容…

现在我们已经学习了 PhpStorm 中的代码覆盖率,是时候看看代码覆盖率的目的了。

代码覆盖率的目的

再次,你心中可能又出现了同样的疑问:我为什么需要代码覆盖率呢?答案并不明显,但了解这一点是很有价值的。你同意代码中存在错误,所以你使用了某些调试工具来找出并移除这些错误。你同意你实现的算法有时会失效,所以你对其进行了测试并修复了它。但你是否曾有过一种感觉,认为你编写的代码中可能存在未使用的行?可能存在一些解释器无法处理的行,也可能存在一些在某个条件下永远不会被满足的行。谁会考虑到这些以及其他许多类似的情况呢?另一个可能会出现在你脑海中的问题是:“当你可以在代码中添加注释行时,多一行代码有什么危害?”答案就在这里。

注释是解释器不会关心的事情,但一个活跃但未使用的行是解释器会关心的事情。这就像你在射击结束后,腰间绑着一把手枪在厨房里走来走去。你需要在厨房里放一把手枪吗?为什么你要随身携带它呢?

第六章。在团队中使用 PhpStorm

在本章中,我们将涵盖以下食谱:

  • 获取版本控制系统服务器

  • 创建版本控制系统仓库

  • 将 PhpStorm 连接到版本控制系统仓库

  • 将 PhpStorm 项目存储在版本控制系统仓库中

  • 将文件提交到版本控制系统仓库

  • 从版本控制系统仓库更新代码

  • 将你的代码与 VCS 仓库同步

  • 检查版本控制系统仓库

  • 从版本控制系统仓库检出项目

  • 创建代码补丁

  • 创建 VCS 标签或分支

  • 为团队创建任务

简介

罗马不是一天建成的。也不是由一个人...

无论你玩什么运动或去哪里,它始终是一项团队运动。他们总是说团结就是力量,分裂就是失败。一个 PhpStorm 食谱作者也曾说过,重新发明轮子是一种应该避免的行为。因此,你应该始终在团队中工作。原因很明显:将任务分配给团队可以更快地完成。

根据软件工程的一个原则,你应该在两个人的团队中编程。这样,你们两个人都将在开发阶段本身发现彼此代码中的错误。

那么,当你在一个团队中工作时,你将如何在一个其他人正在另一个模块上工作的应用程序开发中进行工作?一种方法是用同一台机器编码,这样你就可以从另一个人停止工作的地方继续。但是,等待是否明智?如果你在不同的班次工作,这是可以接受的。但是,如果那个人地理位置上离你很远呢?即使一切都很顺利,如果你需要第三个人加入团队,那个人在哪里工作?如果你工作 8 小时,在任何时刻最多有三个人在项目上工作。这种基础设施的低效使用!

你对代码仓库有什么看法?当有人在你面前说版本控制源控制时,你有什么想法?你对 VCS... VCS 作为版本控制系统有什么了解?

软件版本是什么意思?

为了得到答案,你已经步入了版本控制系统的世界。欢迎!

获取版本控制系统服务器

你必须采取的第一个行动是决定你要使用哪个版本的 VCS。有几种系统可供选择,例如 Git 和 Subversion(通常称为 SVN)。这是一款免费的开源软件,你可以下载并安装在你的开发服务器上。还有一个名为并发版本系统CVS)的系统。两者都旨在为你提供代码版本控制服务。SVN 比 CVS 新,据说比 CVS 快。由于 SVN 是较新的系统,并且为了向你提供有关最新事项的信息,本文将仅关注 Subversion 的功能。

准备工作

因此,最终那个时刻已经到来,你将通过为你的团队获取一个 VCS 系统来开始团队合作。在开发系统上安装 SVN 可以有两种方式:简单和困难。困难步骤可以不考虑而跳过,因为那是为想要为 Subversion 系统做出贡献的开发者准备的。由于你正在处理 PhpStorm,你需要记住更简单的方法,因为你还有更多的事情要做。

如何操作...

安装步骤非常简单。在基于 Debian 的系统中,有这个 aptitude 工具可用,而在基于 Red Hat 的系统中,有 Yum 工具可用。执行以下步骤:

  1. 你只需要发出命令 apt-get install subversion。操作系统的包管理器将为你完成剩余的工作。在很短的时间内,在命令行控制台充斥着消息之后,你将安装好 Subversion 系统。

  2. 要检查安装是否成功,你需要发出命令 whereis svn。如果有消息,则意味着你已成功安装 Subversion。

    注意

    如果你不想在你的开发系统上承担安装 Subversion 的负担,你可以使用商业第三方服务器。但这更多的是一种解决问题的门外汉方法,而且没有任何 PhpStorm 烹饪书作者会推荐你这样做。你是一名软件工程师;你不应该轻易放弃。

它是如何工作的...

当你安装版本控制系统时,你实际上是在安装一个服务器,该服务器为版本控制客户端提供版本控制服务。默认情况下,版本控制服务监听端口 3690 的远程客户端的传入连接。

还有更多...

如果你想要安装较旧的配套软件,CVS,你可以用类似的方式安装,如下面的步骤所示:

  1. 你需要下载 CVS 服务器软件的存档。

  2. 你需要使用你喜欢的解压缩软件将其从存档中解压出来。

  3. 你可以将其移动到另一个方便的位置,因为你将来不需要打扰这个文件夹。

  4. 然后你需要进入目录,编译过程将从这里开始。你需要执行 #. /configure 来创建构建目标。创建目标后,你需要输入 #make install 以完成安装过程。

由于它是较旧的软件,你可能不得不从源代码编译,作为唯一的替代方案。

创建 VCS 仓库

更多时候,期望 PHP 程序员了解一些系统概念,因为经常需要更改 PHP 解释器的设置。这些更改可能是改变执行时间或添加/删除模块等形式。为了开始团队合作,你将不得不通过系统操作来亲自动手。

准备工作

您需要在开发服务器上创建一个新的仓库,这样 PhpStorm 才能作为客户端进行连接。在这里,重要的是要注意 SVN 客户端和 SVN 服务器之间的区别——SVN 客户端可以是以下任何一种:独立客户端或 IDE 等嵌入式客户端。另一方面,SVN 服务器是一个单一的项目。它是在您选择的服务器上持续运行的过程。

如何操作...

在执行此活动时请务必小心,因为一个错误可能会毁掉您的努力。请按照以下步骤操作:

  1. 您需要了解一个名为svnadmin的命令。使用此命令,您可以在服务器上创建一个新的目录,其中将包含代码库。再次提醒,在选择服务器上的目录时请务必小心,因为它将出现在您 SVN URL 的其余部分中。该命令应按以下方式执行:

    svnadmin create /path/to/your/repo/
    
    
  2. 在服务器上创建了一个新的仓库后,您需要对服务器进行一些设置。这只是正常现象,因为每个服务器都需要配置。

  3. SVN 服务器配置位于/path/to/your/repo/conf/下,文件名为svnserve.conf。在文件内部,您需要做出三项更改。您需要在文件底部添加以下行:

    anon-access = none
    auth-access = write
    password-db = passwd
    

必须有一个密码文件来授权允许使用仓库的用户列表。在这种情况下,密码文件将被命名为passwd(默认文件名)。文件中的内容将是多行,每行包含一个用户名和相应的密码,格式为username = password

注意

由于这些文件是按照特定的算法由服务器扫描的,因此您不能在文件中留下故意空格——在这些情况下将显示错误消息。

在进行了适当的设置后,现在您可以启动 SVN 服务,以便 SVN 客户端可以访问它。

您需要发出命令svnserve -d来完成此操作。

小贴士

总是检查您所做的是否正确是一个好习惯。为了验证正确的安装,您需要发出命令svn ls svn://user@host/path/to/subversion/repo/

输出将如以下截图所示:

如何操作...

它是如何工作的...

svnadmin命令用于在 Subversion 服务器上执行管理任务。create选项在服务器上创建一个新的文件夹,该文件夹作为 Subversion 客户端的仓库。

服务器安装时默认创建配置文件。添加到文件中的内容实际上是控制 Subversion 服务器行为的配置指令。因此,所提到的设置防止了匿名访问并限制了某些用户的写操作,这些用户的访问详情在文件中提及。

命令svnserve又是一个需要在服务器端运行的命令,用于启动服务器实例。-d开关表示服务器应以守护进程(系统进程)的方式运行。这也意味着您的服务器将继续运行,直到您手动停止它或整个系统崩溃。

小贴士

再次提醒,如果您选择了第三方版本控制服务提供商,您可以跳过这一部分。

将 PhpStorm 连接到 VCS 仓库

软件的实际效用在于您使用它。因此,在安装了版本控制系统后,您需要准备好使用它。

准备工作

由于 SVN 是客户端-服务器软件,您已经安装了服务器,现在您需要一个客户端。再次提醒,您可能会很难找到好的 SVN 客户端。别担心;客户端已经由工厂内置在 PhpStorm 中。PhpStorm 的 SVN 客户端通过提供有关代码更改的详细信息,为您提供了加速开发任务的功能。所以,继续将 PhpStorm 连接到您创建的 Subversion 仓库。

如何操作...

为了将 PhpStorm 连接到 Subversion 仓库,您需要激活 Subversion 视图。

它位于视图 | 工具窗口 | Svn 仓库。按照以下步骤激活 Subversion 视图:

  1. 在激活了 Subversion 视图后,您现在需要将仓库位置添加到 PhpStorm 中。

  2. 要做到这一点,您需要在您打开的视图的左上角使用+符号,如下面的截图所示:如何操作...

在选择添加选项时,PhpStorm 会询问仓库的位置。您需要提供仓库的完整位置。一旦您提供了位置,您将能够在按下添加按钮的同一 Subversion 视图中看到仓库。

在这里,您应该始终牢记正确的协议。这取决于您在开发机上安装 Subversion 系统的方式。

注意

如果您通过安装程序实用程序(apt-getaptitude)进行了默认安装,您需要指定svn://。如果您已配置 SVN 通过SSH访问,您需要指定svn+ssh://。如果您已明确配置 SVN 与 Apache Web 服务器一起使用,您需要指定http://。如果您使用 Apache 通过安全协议配置了 SVN,您需要指定https://

将 PhpStorm 项目存储在 VCS 仓库中

现在是团队合作的实际开始。即使您和其他团队成员已经连接到仓库,这又有什么优势呢?仅仅连接到版本控制仓库能解决什么问题?正确。真正重要的是您正在工作的代码。正是这些代码让您得以谋生。

准备工作

现在,你应该将项目存储在 Subversion 仓库中,以便其他团队成员可以工作并添加更多功能到你的代码。是时候将项目添加到版本控制了。并不是说你需要从头开始创建一个新的项目来添加到仓库。任何项目,任何你已完成并希望团队现在一起工作的项目都可以添加到仓库。鉴于当前环境中最相关的项目是烹饪项目,你可以尝试添加该项目。

就这样。

如何操作...

为了将项目添加到仓库,请执行以下步骤:

  1. 你需要使用提供的菜单项VCS | 导入到版本控制 | 共享项目(Subversion)。PhpStorm 会询问你一个问题,如下面的截图所示:如何操作...

  2. 选择正确的层次结构来定义共享目标——你的项目将被保存的正确位置。

  3. 如果你希望在代码库中创建标签和分支,你需要选择相应的复选框。对提交的更改提供注释是良好的实践。

当你坐下来创建发布文档时,背后的原因就显而易见了。这也使得变更对其他团队成员来说更容易理解。PhpStorm 会询问你希望工作副本的格式。这与版本控制软件的版本有关。你只需微笑并选择最新的版本号,然后继续,如下面的截图所示:

如何操作...

完成这些操作后,PhpStorm 现在会要求你输入你的凭据。

你需要输入配置文件中保存的相同凭据(参见创建 VCS 仓库配方)或服务提供商给你的凭据。你可以让 PhpStorm 为你保存凭据,如下面的截图所示:

如何操作...

它是如何工作的...

这里值得理解幕后的情况。当你使用 PhpStorm 中的任何 Subversion 相关任务时,有一个内置的 SVN 客户端会为你执行命令。因此,当你将项目添加到版本控制时,代码会被赋予一个版本号。这使得版本控制系统记住代码库的状态。换句话说,当你将代码库添加到版本控制时,你添加了一个检查点,你可以在未来的任何时间点重新访问它,前提是代码库处于相同的版本控制系统下。

这是一个有趣的现象,不是吗?

还有更多...

如果你自己安装了版本控制软件,并且你没有设置将密码以加密文本的形式存储,PhpStorm 会提供一个警告,如下面的截图所示:

还有更多...

将文件提交到版本控制系统

让我们回到一个用例。到目前为止,Dish类的记忆可能已经被厚厚的灰尘覆盖,因为它已经有一段时间没有使用了。向前走,伙计。擦去灰尘,撕掉懒惰,从不同的角度看待事物。

准备工作

在你的大脑上施加一点压力(并且显然是阅读文档)会让你记住你匆忙中创建了Dish类。现在,你已经足够成熟,可以使用 PhpStorm 作为 IDE,你需要证明你在编程方面的实力。你需要使Dish类更加功能化。

如何做...

你可以从查看Dish类中的唯一方法开始。一旦你这样做,你将清楚地看到有一个FIXME标签。正如FIXME标签所述,在允许将其添加到菜肴之前,你应该检查有效的配料名称。这将防止任何不想要的配料被添加到你的菜肴中,从而破坏它。你需要指定两个更改:

  • 你需要将参数默认值设置在方法签名中的某个值。

  • 你需要检查名称是否有效,即非空且不包含无效元素。

因此,你将在Dish类中做出的更改将类似于以下截图:

如何做...

它是如何工作的...

使用像 PhpStorm 这样的 IDE 的一个主要好处是,对象以这种方式显示,你可以从中获得更多信息。当你进行更改时,PhpStorm 开始使用颜色向你指示更改。如果你添加一行,它将以绿色显示,当你删除一行时,它将以一个指向你右侧的灰色三角形表示。当你更改代码中的一行时,它将以蓝色显示。除此之外,当你提交代码时,版本控制编号会附加另一条信息,这条信息本身也非常重要。该信息包含提交代码的用户、提交日期、提交时间和修订号。修订号表示特定文件被更改的次数。

还有更多...

PhpStorm 作为一个谨慎的系统,为你提供了许多可供选择的功能。如果你启用提交后自动更新代码/目录,你可以告诉 PhpStorm 在提交后自动更新代码/目录。

如果你想在提交过程中保持文件锁定,可以在保持文件锁定旁边的复选框中启用此功能。

在提交操作之前,有一些与编程相关的任务。

你可以通过启用重新格式化代码选项来重新格式化你即将提交的代码。

你可以通过选择优化导入选项从即将提交的代码中删除未使用的导入/包含/要求。

你可以通过选择执行代码分析选项来分析你即将提交的代码。

如果你不小心将代码中的 TODO 推送到版本控制,启用检查 TODO选项,PhpStorm 可以警告你。你可以通过点击配置来配置你想要查看的 TODO。因此,在提交之前,PhpStorm 将显示你即将提交的文件/项目中创建的 TODO。

你甚至可以将提交的文件上传到你可能已经配置的 FTP 服务器。因此,PhpStorm 也可以为你部署代码!

PhpStorm 会持续通知你所有你更改的文件。自上次提交以来在本地更改的文件名称以蓝色显示。默认情况下,未更改的文件以黑色显示。如果你正在更改一个文件,而另一个团队成员恰好也在同一文件中进行了更改,将出现文本冲突,此类文件以红色显示。然而,此类冲突主要发生在更新过程中。

注意

你可以更改配色方案为你喜欢的样式。为此,你需要转到文件 | 设置 | 编辑器 | 颜色与字体 | 差异

现在你的更改已完成,你需要提交代码以便其他团队成员可以使用。你需要访问右键点击的上下文菜单,选择Subversion | Commit。会弹出一个对话框,显示你将要执行的操作。一旦你确认更改没有问题,你可以继续提交文件。文件将再次变为黑色,表示它与版本控制系统同步。

小贴士

避免问题

并非你可以无问题地提交和提交。如果另一个团队成员在你更改的同一代码段中提交了代码,版本控制系统将通过提供警告并禁止你提交代码来防止代码的不一致性。它会显示一个消息,指出你正在工作的文件已过时。为了避免这个问题发生,你始终需要基于最新的代码库进行工作。因此,在提交之前,始终要更新。

从 VCS 仓库更新代码

你总是考虑你的团队。你总是认为你会以这种方式工作,成为你团队中最强的纽带。

准备工作

你将充当过滤器,清理团队成员编写的糟糕代码。你将成为你同伴编写的代码的同行评审员。你将为团队中某些人习惯编写的乱糟糟的代码添加文档。所有这些说完,你将如何实现这些目标?每次你计划开始成为团队中的詹姆斯·邦德时,你都必须从版本控制系统获取更新。

如何操作...

不幸的是,为了从版本控制系统中接收更新,PhpStorm 没有提供自动推送通知系统。然而,你可以执行以下步骤:

  1. 您必须手动检查更新。但请放心,您只需记住几个导航链接,就能更新特定的代码、特定的文件夹或整个项目。

  2. 更新链接可在版本控制系统 | Subversion | 更新文件中找到。如果您想更新当前正在工作的文件,请使用以下截图所示的选项:如何操作...

这里,您有一些可选的选项可以做出选择。

您正在工作的项目可能有许多开发版本的分支。假设管理层已经为项目的单独分支或版本做出了规定——可能其中一个分支是一个新主题,以便进行测试,或者有一个单独的分支来优化代码,或者任何可能的排列组合。请执行以下步骤:

  1. 您可以通过选择更新/切换到特定 URL选项来更新到版本控制的特定分支。

  2. 当您选择此选项时,您可以指定一个分支。您也可以指定 URL。

  3. 此文本框默认填充了当前文件的 Subversion 路径。

如果您想回到过去,知道曾经存在但现在已被删除的算法,PhpStorm 也为您提供了相应的选项。为了达到这个目的,请执行以下步骤:

  1. 您可以选择更新/切换到特定修订版本复选框。

  2. 您有一个强制更新选项可供选择,该选项将强制更新所选文件。

当您启用仅在更改的子树中更新管理信息选项时,PhpStorm SVN 客户端将只更新受更新操作影响的管理信息,例如版本号、前一个修订版本和文件校验和相关的版本信息。启用此选项可能会提高更新操作的性能,因为要更新的文件更少,遵循在更短的时间内做更少的简单规则。请注意,在特定情况下,您可能必须执行一个正常的更新。

注意

如果您启用忽略外部复选框,更新将忽略当前文件中更新的所有外部定义。

同样,您可以更新您选择的目录。为了做到这一点,请执行以下步骤:

  1. 您需要选择要更新的目录,访问右键单击上下文菜单,并选择Subversion | 更新

  2. 这次将提供相同的选项,但上下文已从文件更改为目录。因此,当您强制更新时,目录内的未版本化更改将自动添加到版本控制中,整个目录将更新以匹配存储库副本。

    提示

    由于项目也是一个目录,您也可以更新整个项目。方法与更新目录的方法完全相同。

它是如何工作的...

更新操作非常简单易懂。Subversion(以及其他版本控制系统)维护项目的副本。这个工作副本是根据一系列标准创建的,例如修改日期、更改的文本和版本号。当你更新文件/目录时,所有这些以及其他必要的信息都会添加到你的机器上的工作副本中。

还有更多...

如果你希望将本地副本与存储库中的版本控制副本更新,有两种可能性,如下所示:

  • 你正在尝试更新一个你没有做任何更改的文件/目录。在这种情况下,更新将正常进行。

  • 在另一种可能性中,如果你正在进行常规更新,将会有冲突。

版本控制系统会告诉你它正在困惑,不知道应该保留哪个副本进行版本控制:是你的还是他们的?选择接受他们的,即其他团队成员,如以下截图所示:

还有更多...

你需要通过合并文件和解决冲突来平息版本控制系统。冲突在 PhpStorm 中以鲜艳的颜色显示。显然,你也可以修改颜色。红色是冲突行,蓝色是更改行,绿色是新增行。你需要使用引导箭头来在文件之间发送内容,如以下截图所示:

还有更多...

将你的代码与 VCS 存储库同步

你无法控制你出生的地方。你也不能控制你选择的职业:你只需要保持自己与工作带来的挑战同步。

准备工作

程序员面临的最大挑战之一是与团队保持同步。由于对未知发生事情的恐惧,程序员往往会在他们的开发系统中遇到项目版本不匹配的情况。他们倾向于遵循艾萨克·牛顿的第一运动定律。匀速运动的状态已经描述。外部力量是业务需求的变化以及新的任务分配。

解决这个问题的简单方法是始终将你的代码库与版本控制同步。

如何做到这一点...

代码同步需要比其他任何操作都更加小心。原因很明显——你可能会接受错误的代码版本,从而需要更多的时间进行开发。你可以通过多种方式同步代码,以下步骤帮助你了解其中一种方法:

  1. 你需要了解版本控制历史,以确定哪些更改被做出。

  2. 当你选择项目,访问右键单击上下文菜单,并选择Subversion | 显示历史选项时,你可以这样做。

  3. 选择你想要与代码库同步的版本号。访问右键点击上下文菜单并选择显示所有受影响文件选项。如何操作...

  4. 你现在需要选择显示与本地差异选项,PhpStorm 将按层次结构方式显示文件列表,如图所示的前一个屏幕截图。

你需要选择此按钮以查看自所选修订以来更改的文件列表,如图所示的下一个屏幕截图:

如何操作...

你现在可以继续查看文件中的个别差异。你可以选择你想要接受的更改,并跳过你不想接受的更改。

如果你提前很好地了解效果,这可以是一个有用的选项;否则,不要选择这个功能——如果变更列表很大,可能会很烦人。

它是如何工作的...

当你同步时,你只是在执行一个更新操作——这次是手动和有选择性的。因此,同步过程是将更改复制到你的本地工作副本。更改可以是任何东西:新写的一行代码、删除或更改。

检查版本控制系统(VCS)仓库

知道的越多,知道的越多

更常见的情况是,你需要看到内部的情况才能做出决定。

准备工作

拥有额外信息总是帮助你转动最后一颗棋子,这通常在项目的命运中起到决定性作用。因此,你可能想了解代码库的结构,特定目录中的文件,甚至整个项目中的目录。这样的愿望清单是无穷无尽的。

做比仅仅计划更好。

如何操作...

当你下定决心要浏览仓库时,你可以求助于 PhpStorm。要开始查看内部的情况,请执行以下步骤:

  1. 你需要选择版本控制 | 浏览 VCS 仓库 | 浏览 Subversion 仓库。一旦你这样做,你将能够看到你在使用 PhpStorm 时添加的所有仓库,无论项目如何,如图所示的下一个屏幕截图:如何操作...

    你可以从可用位置列表中选择所需的仓库位置。

  2. 一旦你选择了一个位置,你可以通过双击选中的条目来浏览仓库。除此之外,你还可以做更多的事情。一旦你右键点击并访问上下文菜单,就会有多个选项可供你选择。

  3. 如果你选择新建 | 仓库位置,你可以创建一个新的仓库位置。

  4. 如果你选择新建 | 远程文件夹选项,你可以在选定的仓库中创建一个新文件夹。你需要指定文件夹将被知晓的名称以及要显示给此添加到仓库的消息。记得团队合作吗?这就是新建 | 远程文件夹的外观:如何操作...

如果你选择Show History选项,你可以查看所选仓库位置的修订历史。你能回忆起还有其他查看 Subversion 历史的方法吗?

如果你想在本地机器上检出项目,PhpStorm 允许你通过提供一个名为Checkout的选项来完成。这类似于酒店结账,你离开酒店时带着所有的行李。在这里,将 Subversion 服务器比作酒店,将实际代码比作行李。然而,这并不是一个 100%的类比,因为你通常不会在酒店房间结账时检查别人的行李。那些是经验丰富的专业人士(有意为之)表演的特技。不要在家里尝试(无意为之)。

当你在浏览时,可能需要找出在分支或标记版本中另一个代码库版本的不同之处;你可以使用Compare with选项来完成这个操作。一旦选择,PhpStorm 会提供一个信息框,你可以用它以你喜欢的任何方式查看信息。你可以选择你想要比较的版本。在此需要注意的是,比较的顺序很重要,因为你也有进行反向比较的选项。你可以通过启用Reverse diff选项来实现这一点。

在获取文件差异时,PhpStorm 为你提供了两种选择。如果你选择Graphical Compare选项,你可以为你的眼睛提供视觉享受,或者你也可以将差异保存到当前目录中名为diff.txt的文本文件中。

你也可以在当前选定的仓库中进行搜索。

如果你希望搜索特定作者所做的更改,你需要启用Author选项并提供有效作者的姓名。

如果你希望搜索在某个特定日期之后所做的更改,你可以启用After选项,并从点击此选项旁边的日期选择器窗口中设置所需的日期。

当你想搜索到某个特定日期之前所做的更改时,你需要启用Before选项。日期选择器窗口的显示方式与之前的情况相同。

提示

如果你记得版本号,你可以通过修订号浏览更改。你可以选择修订号大于From选项且小于To选项的更改。

它是如何工作的...

当你完成指定搜索条件后,PhpStorm 会向你展示符合你选择标准的变化列表。

PhpStorm 表示你可以利用这些信息做更多的事情,并为你提供了修改搜索条件、基于更改日期或更改作者进行分组,以及在此结果中执行基于正则表达式的搜索的选项。要查看可用的选项,你只需右键单击并访问所选项目的上下文菜单。你将获得一系列一目了然的选择,例如刷新以重新加载搜索结果;过滤以再次指定搜索条件;显示详细信息以快速查看修订详情;创建补丁以创建所选修订的差异补丁文件;撤销更改以撤销所选修订中做出的更改,并将文件/目录回滚到立即之前的状态;以及编辑修订注释以修改在创建所选修订时传递给版本控制系统的注释。

艺术是长久的,而生命是短暂的,对吧?

从 VCS 仓库检出项目

检出的现象非常有趣。你(通常)从酒店房间中检出你的行李;你(大多数时候)告诉你的朋友:“伙计,看看我的新大屏手机”;你(犹豫着)从版本控制中检出代码。检出究竟意味着什么?这似乎更像是一个时髦词...检出,检出,再检出!

准备工作

理解上下文是你需要明白的。一个词的意义会随着上下文的变化而变化。在当前上下文中,你需要做你犹豫不决的事情。因此,检出代码是版本控制系统提供的一种现象,其中你取出代码库的最新版本并将其下载到你的开发计算机上。这种下载不仅仅是简单的下载,它为你提供了在版本控制下可用的最新代码版本,并使你了解截至当前日期对代码库所做的更改列表。因此,当你检出一段代码时,你也会了解到代码的历史。

在你得到如何做到这一点...部分中的答案之前,你需要知道为什么你应该这样做。团队是你开始思考版本控制时谈论的内容。因此,如果团队有新成员加入,让新成员开始处理现有项目的唯一方法就是检出。如果你的开发机器已经改变,并且你希望从你离开的地方继续工作,你甚至可以使用检出。

如何做到这一点...

从版本控制中检出代码是每个人的最爱。请执行以下步骤:

  1. 你可以通过访问版本控制 | 检出VCS | Subversion菜单项来极其容易地做到这一点。

  2. 一旦你选择了这个选项,你将看到一个新窗口,其中列出了你在 PhpStorm 中连接的 Subversion 仓库列表,无论项目如何,如下截图所示:如何做到这一点...

在选择了适当的版本后,继续操作时,PhpStorm 会询问它应该将检出的代码库保存在哪里。你需要指定这一点,如下面的截图所示:

如何操作...

当你设置目标位置时,PhpStorm 会保持好奇。它会询问你一般的检出选项,例如你想要检出代码的深度,你是否想要检出最新代码或只检出至某个修订,以及你是否想要选择外部定义,如下面的截图所示:

如何操作...

它是如何工作的...

在设置完所有选项后,你现在可以轻松地坐下来享受美景。PhpStorm 会检查代码,并在你的本地(开发)机器上以有组织的方式保存。

创建代码补丁

这通常用三个简单的陈述来说明:

  • 做它

  • 做对它

  • 立即行动

语句很简单,但意图并非如此。每个经理都希望任务能被完成,而作为程序员的你,如何完成这个任务成了你的头疼问题。你常常会写出错误的代码。不幸的是,痛苦并没有结束;你会在一天结束时偶然将错误代码推送到 Subversion,告诉你的经理你一天的工作内容。在这场匆忙中,你意外地将一些错误推送到版本控制。现在,将有两种类型的资源浪费:

  • 该成员(以及任何其他做过同样事情的成员)将花费时间来定位错误——浪费了人力

  • 找到错误后,你必须撤销更改并做一些其他更改——浪费了前一个人的时间(当你推送有错误的代码时)

不仅如此,这还会滥用版本控制系统,因为当错误进入版本控制时,使用版本控制的初衷就被抵消了——多个人会做相同的工作——再次,重蹈覆辙。

准备工作

因此,作为这种浪费的源头,你必须考虑一个解决方案来解决这个问题。解决方案将是使用 SVN 补丁。补丁是在你创建它时生成的文件。显然!所以,补丁是一个只包含差异文本和关于更改所做的文件细节的文件。因此,补丁可以应用于文件,并且可以在以后撤销。因此,代码更改只有你给过这个补丁文件的人才能看到。优势?应用补丁的人可以审查你打算做出的更改,如果有些错误可见,补丁可以从代码库中移除,并且你可以被告知你需要做更多工作来创建无错误的代码。

你可以将补丁文件的应用过程比作裁缝。当你做饭披萨时不小心烧坏了衬衫(业务需求发生了变化),你去找裁缝修补你的衬衫(业务团队来找你以使新功能运行)。裁缝(你)找到一块类似的布料,通过缝合它来覆盖你衬衫烧毁的部分(代码库)。如果你不喜欢补丁(审查员在代码中发现了错误),你可以要求裁缝移除补丁并尝试另一种颜色(审查员会要求你制作并实施另一种算法)。裁缝很容易撕掉补丁并尝试另一种颜色(你/审查员从代码库中移除补丁)。这个过程会一直进行,直到你对补丁满意(直到审查员发现你的代码运行良好)。裁缝最终正确地完成缝合并将衬衫交给你(你提交代码并将其交给发布工程师继续处理)。

总结一下,你可以在 PhpStorm 中创建代码补丁。

如何操作...

如果你想在 PhpStorm 中创建 Subversion 补丁,请执行以下步骤:

  1. 你需要在顶部菜单中查找(查找菜单项),找到版本控制,点击它,然后找到创建补丁选项,PhpStorm 会显示你可能熟悉的窗口。

  2. 是的,这是一个类似于提交窗口的窗口,不同之处在于将提交按钮替换为创建补丁按钮。

    并且,功能也有所不同。你需要指定一个注释,该注释最终将作为补丁文件的名称(空格用连字符替换),如下面的截图所示:

    如何操作...

  3. 默认选项最容易理解和执行。一旦你指定了补丁信息将要创建的位置(名称和位置),PhpStorm 就会在那个位置创建补丁,如下面的截图所示:如何操作...

  4. 如果你选择反向补丁选项,PhpStorm 将反转比较标准——在默认情况下,它保持了最新版本(Head)作为比较的基础,并将这个版本中的更改视为新的。

  5. 在创建反向补丁时,PhpStorm 会将立即前一个版本作为基础,并将这个版本中的更改视为新的。

  6. 如果你选择将基版本文本(们)选入补丁文件,这意味着你要求 PhpStorm 将当前版本中的文件内容放入补丁文件中。因此,补丁文件的大小将会增加。在这里,重要的是要注意,你可以选择你希望在补丁文件中包含的文件基版本。

在完成必要的选项并启动补丁文件创建过程后,PhpStorm 会显示一个成功消息,并附带一个选项,现在可以转到补丁文件的位置,如下面的截图所示:

如何操作...

现在,你可以将这个补丁文件传递给代码审查员,关闭你的机器,安全地开车回家,无需担心浪费任何资源。

它是如何工作的...

当你创建补丁文件时,你实际上创建了一个包含两个文件或更精确地说,修订版本之间差异的文件:基本修订版本和即将到来的修订版本。因此,补丁文件包含以下信息:

  • 文件名和基本修订版本

  • 被修改的行号

  • 内容的差异

一个典型的补丁文件看起来如下:

--- lib/dml/mysqli_native_moodle_database.php (revision 258)

变更是对此文件和指定的修订版本进行的,如下所示:

+++ lib/dml/mysqli_native_moodle_database.php (revision )
@@ -871,13 +871,20 @@

修改的行号是 871, 删除了 13 行,并增加了 20 行。看看下面的代码:

list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
$rawsql = $this->emulate_bound_params($sql, $params);
-
+ $id = 0;
+ try{
- $this->query_start($sql, $params, SQL_QUERY_INSERT);
- $result = $this->mysqli->query($rawsql);
- $id = @$this->mysqli->insert_id; // must be called before query_end() which may insert log into db
- $this->query_end($result);

- 符号表示内容已被删除。看看下面的代码:

+ $this->query_start($sql, $params, SQL_QUERY_INSERT);
+ $result = $this->mysqli->query($rawsql);
+ $id = @$this->mysqli->insert_id; // must be called before query_end() which may insert log into db
+ $this->query_end($result);

+ 符号表示内容已被添加。看看下面的代码:

- if (!$id) {
+ }catch (Exception $e){
+ $errorMessage = print_r($e, true);
+ $errorMessage = "\nNew Error on ". date('d:m:Y H:i:s'). "\n".$errorMessage."\n\n";
+ file_put_contents("/tmp/errorMessage", $errorMessage, FILE_APPEND);
+ }
+
+ if (!$id || $id==0) {
throw new dml_write_exception('unknown error fetching inserted id');
}

快乐地打补丁。

创建 VCS 标签或分支

人类大脑是一个超负荷的机器。它很容易忘记事件、事物或计划。需要持续的努力来让大脑记住事物。由于大脑的大部分区域都用于视觉感知,最普遍的使用方法是提供视觉提示。视觉提示的作用与在 PhpStorm 烹饪书中的常规书签相同,它们让你记住你正在阅读的章节以及何时阅读。

准备工作

PhpStorm 提供了一个功能,你可以创建视觉上吸引人的标签,即标签。

标签是视觉标签,让你和你的团队能够知道哪个修订版本对你来说特别。因此,你可以创建视觉上吸引人的标签或标签来表示特殊事件,例如 Release Version 2.3Bug fixes for V2.2 等。那么,提示在哪里呢?提示就是名字。为什么是视觉的?因为你可以轻松记住名字和视觉元素。

如何操作...

标签过程从你决定创建标签的时间开始。

它应该是一个描述性的标签,因为如果你在创建标签的时候没有完全清醒,你可能会得到像 Tag 1My Tag 这样的名字。这会导致资源浪费和技术滥用。要创建一个标签,请执行以下步骤:

  1. 无论如何,如果你想创建一个新的标签,你需要在选择 VCS | VCS Operations 弹出菜单时选择可用的 Branch or Tag 选项,如下面的截图所示:如何操作...

    当你这样做时,你会看到 PhpStorm 会提出问题,让你感到宾至如归,如下面的截图所示:

    如何操作...

  2. 你需要在你的开发机器上指定你希望从标签中复制文件或文件夹的源,通过启用 Working Copy 选项并指定源文件路径来实现。

  3. 如果您需要指定要复制的文件或文件夹,您需要选择仓库位置选项,并指定当前仓库中的确切位置和所需的修订号或Head(最新修订)。

  4. 然后,您需要指定目标位置,您将在那里保存标记版本。

您可以通过指定基础 URL 和标签名称来在仓库中指定位置。这个标签名称将为您提供一个视觉提示。

注意

您也可以指定一个任意位置,例如仓库位置,甚至是您的开发机器上的位置。

它是如何工作的...

一旦您确信某件事是可行的,那么进一步探索幕后的情况以及是什么让这件事工作,将会是一次极好的体验。所以,分支或标签创建过程以相同的方式运作——当您在仓库中创建标签或分支时,您只是从一处复制文件到另一处。是的,这就是大多数工程师都擅长的复制(无意中开玩笑)。因此,有四种组合可用:

  • 您从本地工作副本复制到本地工作副本

  • 您从本地工作副本复制到同一仓库中的另一个位置

  • 您从另一个仓库位置复制到您的本地工作副本中的位置

  • 您从另一个仓库位置复制到同一仓库中的另一个位置

    小贴士

    这不是强制性的,但始终建议您在进行任何操作时添加注释——您可以添加描述性注释,以便您能够将此更改与未来的某个操作联系起来。

还有更多...

在学习了如何在仓库中标记更改后,您可以通过继续创建分支来更深入地探索知识海洋。标签和分支之间的相似之处在于它们都是具有特定名称的文件夹。它们在所服务的目的上有所不同。虽然标签可能对小的更改有用,但分支是更大图景的一部分。

一个用例将使场景对您更清晰,您将能够区分这两者。假设技术团队已经发布了一个版本,并且他们认为这是该版本最后的新开发。因此,您可以创建一个名为Version 2.3 final的标签,向其中添加内容,并永远保留它。因此,在未来任何时候,无论何时您需要回顾您的项目,您都将能够识别出Version 2.3 final意味着这样的一个版本,具有这样的变化。

创建分支与创建标签类似,因为它们都是仓库目录。执行以下步骤:

  1. 要创建一个新的分支,您需要转到Subversion视图,从项目视图中选择适当的目录,并访问右键单击上下文菜单。

  2. 选择Subversion菜单项,然后选择分支或标签选项。一旦您这样做,就会弹出一个熟悉的窗口。您需要填写创建分支所需的基本信息,例如:

    • 你从哪里获取要推送到 Subversion 的文件:这个源可以在你的本地开发系统中的某个地方(你默认选择的文件/文件夹)或仓库位置(你也可以指定修订号)。

    • 你将放置分支的目的地:这同样需要在你的本地开发机器上的完整路径名或指向仓库位置的 URL。在此需要注意的是,仓库位置必须与你的源代码所在的同一仓库。

    • 你希望添加的注释,以便你和团队记住分支创建的目的。

因此,你创建一个标签来确保修订在仓库中永远安全。你创建一个分支来制作一个安全稳定的代码版本——分支被创建;你在上面工作,进行测试并获得批准,然后将它合并到主分支。

这一切都是感知的问题

为团队创建任务

你是否曾经想过如何创造伟大事物?人们是如何成功构建出如此高效的大型系统的?当他们决定迈出一步,尝试额外努力时,他们的思维和心态是怎样的?

这个问题的答案相当简单。千里之行,始于足下。所以,当你开始思考与团队一起工作时,你决定使用版本控制。你继续前进,在版本控制中学习技巧。现在,是你迈出一步,尝试额外努力的时候了。结合你所获得的知识,准备好探索你可以创建团队任务的一种方式。

准备工作

你想要创建一个团队任务,以便你可以设定你的团队中哪个程序员需要关注代码的哪个部分。你可以通过结合 TODO(还记得创建 TODO 任务吗?)和版本控制的强大功能来实现这一点。因此,任何程序员都可以很容易地知道某个任务已经被分配,并且需要有一个适当的发展计划。这对团队大有裨益——你将引导他们走向正确的道路。

这在软件工程中的极限编程(eXtreme Programming)范式中的同行代码审查过程中也扮演着一定的角色,其中你编写代码,你的同行审查你的代码。然后,同行会指出你代码中可能存在问题的部分。因此,一旦你将带有任务给你的代码推送到版本控制,同行就可以推送他们所做的更改,包括需要你修复或考虑的任务,或者任何可能出现的即时需求。

如何做到这一点...

创建一个任务并不是一个困难的任务(有意为之)。所以,如果你想指向你团队中的另一个成员,请执行以下步骤:

  1. 你只需要继续你旧的编程风格,但稍作修改:无论何时你觉得需要做更多的工作。

  2. 你只需要添加一个 TODO,然后描述你希望引起团队注意的任务。在审查代码时创建一般团队任务的实际流程如下:

    • 找到一段代码

    • 仔细阅读

    • // TODO <随后是待完成的任务,例如添加文档,团队>

    • 将代码提交到版本控制

当你自己在编写代码时,你可以添加一个 TODO 来创建一个任务,让团队思考特定的方向。流程如下:

  • 编写(精炼)的代码——你无法承担犯错的代价

  • 找到一个你认为没有完全实现的逻辑

  • //TODO <随后是待完成的任务,例如找到一些万无一失的正则表达式,团队>

  • 将代码提交到版本控制

当你想将任务分配给团队时,可以使用 TODO 用户后跟你认为最适合完成工作的程序员的姓名。流程如下:

  • 仔细阅读更改后的代码。

  • 在你的开发系统上测试代码。

  • 找出可以进行的改进,并根据团队成员的能力分组。

  • 写 TODO 和目标程序员的姓名,然后针对你发现的每个可能的改进写上注释。一些示例 TODO 如下:

    • //TODO Alice: 这个部分需要移除不必要的变量

    • //TODO Bob: 循环内的操作可以移到循环外以降低执行时间

  • 将代码提交到版本控制。

    小贴士

    这只是其中一种方法——你将是那个发现越来越多版本控制使用方法的人。

它是如何工作的...

当你创建团队任务时,你只需创建一个 TODO 任务并将其推送到版本控制。因此,从实际意义上讲,你是在利用 PhpStorm 的 TODO 功能。所以,你的 TODO 实际上是通过 PhpStorm 的帮助传递给团队成员的,因为它是用 PhpStorm 构建的解析器,可以识别 TODO 关键字。因此,当团队从版本控制中获取更新时,这个 TODO 也会包含在你的工作副本中。所以,当其他程序员选择 TODO 视图时,意图是显而易见的。

当你为团队中的特定程序员创建 TODO 任务时,情况也是如此。因此,当团队中的每个人都从版本控制中获取更新时,同样的 TODO 现在包含了程序员的姓名。这使得团队成员能够正确地专注于他们的任务。

团队任务不仅帮助团队更专注于分配的任务并投入更多精力,还试图减轻分配工作的繁琐任务带来的压力。

PhpStorm 再次来拯救你!

第七章. PhpStorm 和 Phing

在本章中,我们将涵盖以下主题:

  • 连接 Phing 和 PhpStorm

  • 捕获 Phing 构建文件语法问题

  • 使用 Phing 构建 PhpStorm 应用程序

  • 使用不同的构建文件

  • 用 Phing 创造奇迹

  • 使用 Phing 构建视图

简介

奶奶曾经说过:“不要复制,要原创”。软件工程则说:“不要重新发明轮子”。

你信任谁?如果奶奶不是软件工程师,那么就信任软件工程吧!

他们通过这种方式复制并构建了伟大的事物。说“复制”可能会引起争议,所以基于一个更符合政治正确的术语来描述复制,我们用灵感。因此,用外交术语来说,他们是受到了现有软件的启发,并完全创建了一个新的软件。

但是,这是邪恶的吗?如果那个软件不存在呢?如果那个软件非常有用呢?

在这张黑白图片中添加颜色,这里就有软件:一个为另一种语言 Java 提供的构建工具,名为 Ant。PHP 爱好者(程序员)们想到了拥有一个类似的构建工具,于是有好事者辛勤劳作,为这项任务创造了Phing。因此,Phing 成为了 PHP 的构建工具,据说 Phing 是基于 Ant 的。

一些 PHP 程序员可能会说,当 PHP 被解释时,为什么还需要一个单独的工具呢?当 PHP 源代码必须提供给客户时,创建一个捆绑包有什么用?一个简单的包含 PHP 脚本的目录就足够了。对这个问题的最简单、最恰当的回答是,当你是一名软件工程师时,你应该总是让一切自动化——即使是这个最简单的任务。Phing 自动化了许多过程:在 PHP 环境中你能想象到的一切。你可以创建归档、检出代码、部署代码、清理日志、备份代码——只需思考,就会有 Phing(有意为之的押韵)。

当你与 Phing 一起工作时,你还需要了解底层发生了什么。所以,你根据一些规则写下 XML 格式的指令。这些基于 XML 的指令被称为 Phing 的任务。这些任务可以有很多,包含这些任务的文件也可以有很多。在这里值得注意的是,在分离任务(或分组任务)时,你需要使用适当的(并且有文档记录的)智慧,因为越坚持软件工程的原则,你将越容易更好地处理模块化。正如已经提到的,Phing 本身是用 PHP 编写的代码。当执行时,它会读取你编写的 XML 文件,并忠诚地遵循其中的内容(前提是 XML 文档本身格式良好,并遵循 Phing 的 XML 规则)。你可以把这个 XML 文件称为构建文件,因为这是它的常见名称。

你注意到 Phing 有一个奇怪的名字吗?它听起来更像是无线电中继之间的商业广告的指示性声音。开玩笑的,Phing 是一个递归缩写词——你还记得第一次听到这个词的时候吗?只需记住,当你什么都想不起来的时候,最好从开始的地方(双关语)开始。Phing 代表PHing Is Not Gnu's make。愿上帝保佑那些名字很短的人。

连接 Phing 和 PhpStorm

在获取了一些关于 Phing 的非常基本的信息之后,现在是你进行实际操作的时候了!如果没有 PhpStorm,操作将集中在 Phing 上,但既然你在使用 PhpStorm,你需要从多个角度来考虑。因此,对你来说,一个可能的路线图可能是获取 Phing,在你的开发机器上本地安装它,并告诉 PhpStorm Phing 已经安装,并且需要与 Phing 同步工作。实际上,PhpStorm 正是利用了 Phing 提供的功能。

在我们深入探讨构建文件的深度之前,值得注意 Phing 的一些主要特性,如下所示:

  • 简单的 XML 构建文件

  • 提供了丰富的任务集

  • 通过 PHP 类轻松扩展

  • 平台无关性

  • 无需外部依赖

    小贴士

    如果你想了解更多关于 Phing 任务的信息,我建议你访问 Phing 的官方网站(www.phing.info/)。

如何做到这一点...

获取 Phing 确实是每个人的最爱。你可以使用命令wget -c http://www.phing.info/get/phing-latest.phar将其作为 phar 下载。你可以在终端(通过Alt + F12访问)中运行此命令。一旦这样做,在有工作的互联网连接的情况下,你可以下载这个 phar。你需要注意文件被加载的路径。建议你将可执行文件移动到一个不修改的公共文件夹下(没有与之关联的写权限)。这样做并不是因为它会有错误——这样做是良好的实践,并且使操作系统文件和目录保持组织。

获取 phar 后,是时候告诉 PhpStorm 关于 Phing 的信息了。你需要执行以下步骤:

  1. 前往项目视图。定位到外部库

  2. 访问右键点击上下文菜单,并选择配置 PHP 包含路径选项。

  3. 提供你下载(或移动)包的完整路径。

Bingo!你成功告诉 PhpStorm 你为开源项目添加了一个新的库。

小贴士

要使 Phing 对所有运行 PHP 的应用程序可用,你可以将其添加到 PHP 主包含路径中——类似于/usr/share/php5

在这个时候,如果你希望检查安装 Phing 时应用了哪些更改,你将不会成功。你将无法在任何地方看到任何与 Phing 相关的菜单项。你将无法看到任何额外的图标,也无法看到任何与 Phing 相关的额外视图。你可能会开始考虑在 Phing 安装过程中遗漏了某些东西。不用担心,请继续关注!

它是如何工作的…

要释放 Phing 的力量,你需要执行它。要执行它,你需要安装它。但你已经安装了 Phing,你不确定它是否被正确安装。这似乎是一个恶性循环。Phing 需要一个输入文件来理解它需要做什么。这被称为构建文件。因此,你需要在你的项目内部创建一个新的构建文件。构建文件是一个 XML 文档,并基于一些规则。默认名称是 build.xml。所以,一个非常基本的构建文件看起来可能像以下代码:

<?xml version="1.0" encoding="UTF-8"?>
<project name="firstTask" default="firstTask">
<target name="firstTask">
<echo message="Testing Message 12...4"></echo>
</target>
</project>

完成这些后,你需要做以下事情:

  1. 打开项目视图并选择构建文件。

  2. 访问右键单击上下文菜单。

  3. 将会有一个名为添加为 Phing 构建文件的新选项(神奇!)。选择该选项。

为了检查集成是否成功,你可以选择视图 | 工具窗口,你将能够看到一个新选项可用,Phing 构建。如果你能看到这个新选项,恭喜你,你已经成功将 Phing 连接到 PhpStorm。

注意

在创建构建文件时,PhpStorm 需要至少指定一个目标。如果你留一个构建文件为空,PhpStorm 将成为你的好朋友。

还有更多…

由于 Phing 是用 PHP 编写的软件,PhpStorm 希望让这个软件在其范围内。所以,你添加包含路径到项目中以实现这个目标。当 PhpStorm 拥有 Phing 在其范围内时,它会尝试为 Phing 创建一些选项。为此,它会查找以找到构建文件和目标。一旦找到目标,它就会理解目标并创建必要的选项。

捕获 Phing 构建文件语法问题

现在你已经努力将 PhpStorm 和 Phing 连接起来,你一定知道是什么驱动着 Phing。是什么让你能够用 Phing 做出奇迹?是什么让你的生活变得更轻松,让遵循软件工程原则变得更简单?你必须想到的名字是构建文件。是的,正是构建文件控制着 Phing 的行为。是的,使用构建文件,你可以用 Phing 做出奇迹。是的,使用构建文件,你可以以干净的方式执行任务——从而遵循软件工程的原则。

准备工作

写一个新的构建文件来使用 Phing 执行任务是完全正常的。但这个问题很突出——你如何检查你写的构建文件在语法上是否正确。来吧,如果你说你写的时候没有犯错误,那你一定是 JARVIS,而不是人类。犯错是人类的本性,检查和移除错误是PhpStorm-ine

如何操作…

在开始编写构建文件之前,你需要了解一些非常基本的规则,这样你至少可以测试 Phing 中的演示或 Hello World 操作。(是的,你听得很对:使用 Phing 创建一个Hello World消息是可能的。)只有当构建文件:

  1. 文件包含一个开始和结束项目标签。应该只有一个,并且它应该是 XML 树的根节点。在项目标签内部,文件应该至少包含一个目标标签:例如propertytstamppropertyprompt这样的标签。

  2. 现在,重新查看相同的构建文件,你将能够更好地理解构建文件——第二次尝试比第一次尝试让你更加成熟。在这里,看看以下代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="hello-world" default="firstTask">
    <target name="firstTask">
    <echo message="Testing Message 12...4"></echo>
    </target>
    </project>
    
  3. 为了检查语法,必须注意检查。底部状态栏提供了一个图标。你需要点击它,将省电模式设置为关闭,并将高亮级别设置为检查,如下面的截图所示:如何操作…

  4. 是时候让你在构建文件上玩一玩了。不用担心,有本地历史记录来帮助你——你可以随意回滚一些更改。所以,无论何时你在语法上犯错误,PhpStorm 都会显示错误:

    • 如果你指定了一个错误的开始标签,最近的匹配标签将显示红色下划线,并且状态栏显示信息开始标签有错误的结束标签

    • 错误的结束标签名称将在错误的标签和最近的匹配标签以及底部状态栏中显示红色下划线,并且状态栏显示信息错误的结束标签名称

    • 如果你指定了一个在 Phing 的规则列表中未定义的标签,问题将以多种方式显示,如下面的截图所示:如何操作…

    • 如果你指定了一个对于该标签未定义或不允许的属性,错误的属性会变成红色,并且状态栏会显示信息属性 在此处不允许

    • 如果你忘记指定一个标签的结束标签,状态栏将显示信息元素 未关闭

    再次使用PhpStorm,证明了 PhpStorm。

小贴士

由于你将经常为 Phing 编写任务,你也可以为构建文件创建一个新的模板。为此,你需要选择文件 | 新建选项,并选择编辑文件模板选项。在出现的窗口中,你需要添加此模板的名称(它将在你选择文件 | 新建时出现)和此模板的扩展名(你需要指定.xml),并放入你将始终需要的最基本构建文件的内容。点击确定将保存此模板。

以下截图显示了 Phing 文件:

如何操作…

它是如何工作的…

PhpStorm 会实时检查代码。因此,检查的一般规则也适用于构建文件。此设置可以通过选择文件 | 设置 | 检查 | Phing | Phing 检查来打开或关闭。所以,随着你继续输入,检查器会继续检查你输入的内容,并继续以视觉方式显示警告。

还有更多…

如果你想要禁用检查,你可以这样做,以至于所有检查都被关闭。虽然不推荐,但在处理大文件时可能会很有用。

使用 Phing 构建 PhpStorm 应用程序

因此,现在是时候使用 Phing 进行一些实际操作了。现在是时候尝试使用 Phing 的问题(并受到其射击的伤害)了。现在是时候为你的事业做些有用的事情了,你是这个事业的支柱。系好头盔,在阳光下开始工作。

在需要编译的其他语言中,构建的一般含义是编译代码,链接对象,并创建可执行文件。然而,在 PHP 中,你不能编译代码;它是被解释的,亲爱的:你可以模拟构建过程。如何?请耐心等待。

准备工作

首先,你需要回忆一下你曾经饿过!你一定不要忘记生活中的某些事情——其中之一就是你的饥饿。它让你意识到你仍然需要努力工作来赚取面包以平息这种饥饿。所以,当你饿的时候,你只是进入你的厨房,试图为自己做些披萨。对吗?如果你希望传递给你做披萨的相同系统,你的行动会是什么?你需要为 Phing 创建一个构建文件,并在其中编写一些目标和操作,以便你能够将必要的组件组合在一起,并以一个单一单元传递出去。

如何操作…

要创建一个新的构建文件,你需要执行以下步骤:

  1. 前往项目视图。

  2. 选择适当的目录,并在右键菜单中选择构建文件类型。

  3. 你将创建一个看起来像以下代码的构建文件;不用担心这个代码——你将会详细了解它:

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="pizzaCookingSystem" default="compressComponents">
    <target name="bundleComponents">
    <echo message="Creating a package directory." />
    <mkdir dir="./package" />
    <echo message="Making a list of components to bind together." />
    <copy file="../Controllers/Dish.php" tofile="package/Dish.php" />
    <copy file="../Controllers/PizzaDish.php" tofile="package/PizzaDish.php" />
    <copy file="../Controllers/PizzaDishTest.php" tofile="package/PizzaDishTest.php" />
    <echo message="Bundling process complete."></echo>
    </target>
    
    <target name="compressComponents" depends="bundleComponents">
    <echo message="Compressing Contents of the bundled components." />
    <zip destfile="package.zip">
    <fileset dir="package" >
    <include name="*" />
    </fileset>
    </zip>
    </target>
    </project>
    

它是如何工作的…

最后,你理解 Phing 驱动原理的时候到了。因此,<project name="pizzaCookingSystem" default="compressComponents"> 创建一个项目元素,并将其绑定到具有name属性的命名空间。default属性定义了 Phing 将选择执行的目标。如果你将 Phing 构建文件视为树形结构,项目是树的根节点。《target name="bundleComponents"> 创建一个新的目标元素,它是你想要执行的操作的容器。因此,你希望执行的所有任务都写在目标组件内部。目标是通过name`属性选择的。如果你将 Phing 构建文件视为包含节点和叶子的树形结构,目标元素是树的一个节点。

<target name="compressComponents" depends="bundleComponents"> 是另一种带有附加属性depends的目标元素写法。因此,当你指定depends属性时,你告诉 Phing 引擎这个目标元素依赖于其他目标元素。重要的是你要知道,当你指定depends属性时,该目标元素将先于当前元素执行。

<echo message="Creating a package directory." /> 创建一个元素,用于向控制台输出消息。显示的消息将取决于消息属性的内容。(还记得显示Hello World吗?你的笑容真迷人!)

<mkdir dir="./package" /> 创建一个元素,在当前目录中创建一个新的目录。这与*nix系统下的mkdir命令同义,它接受相对路径和绝对路径作为目标位置。

<copy file="../Controllers/Dish.php" tofile="package/Dish.php" /> 执行从文件属性指定的文件位置到tofile属性指定的文件位置的文件复制操作。这与*nix系统下的cp命令同义,并接受相对或绝对文件路径名。

<zip destfile="package.zip"> 创建一个元素,用于处理 ZIP 格式的文件压缩。destfile属性指定了压缩文件的名称,该文件将是输出。输出路径可以是相对路径或绝对路径。

<fileset dir="package" /> 创建一个元素,用于设置要选入压缩输出文件的文件。换句话说,这将从由dir属性指定的目录中获取文件。

如果你想要将选定的文件包含在包中,你可以创建一个include元素,并指定你想要添加到输出压缩文件中的文件名(<include name="*" />)。通配符字符在这里是可以接受的。因此,星号(*)意味着将选择文件集元素dir属性内部指定的所有文件。

现在,你可以自豪地说,你拥有了利用 Phing 的能力。这是你帽子上的另一根羽毛,对吧?表现优秀,继续保持!

使用不同的构建文件

经常发生的情况是你手头上有相互独立且互斥的任务。软件工程的原理总是反对将任务组合在一起——模块化是所倡导现象的正确名称。你和 Phing 的情况也是如此。如果你有一系列任务要执行,你有两条路可以选择:较短的和较长的。较短的路会迅速带来结果,但你的朋友,软件工程,会感到不悦。较长的路一开始可能会让你感到烦恼,但亲爱的朋友,这将让你更接近软件工程。

一个明智的决定是与软件工程为友,走更长的路线。因此,你将为每个任务创建单独的构建文件。但要注意,决定任务的分组本身是一把双刃剑——它两面都锋利。

如何做…

根据任务的性质分组后,你现在需要专注于 Phing 如何在你繁忙的日常生活中帮助你。你只需要遵循规则:

  • 组别:将任务分组是开始的重要步骤。你需要创建一个预期包含任务的目录(构建文件)。这并不是说会有错误:这是遵循的良好实践。一个查看你的代码层次结构的人将能够轻松地理解你的意图。

  • 创建:创建实际的构建文件是下一步,你不仅需要做,而且要非常小心。由于这是工作马,你需要确保程序结构是最小的——冗余的行会让你困惑。你需要根据你分组的单个活动来编写任务。确保你不要把业务团队落下!因此,要创建构建文件,选择文件 | 新建 | Phing 构建文件选项,并在其中编写任务。如果你没有为构建文件设置任何模板,你需要选择文件 | 新建 | 文件,并指定具有.xml扩展名的文件名。

  • 设置:像往常一样,你的朋友 PhpStorm 需要考虑到你的工程需求。是 PhpStorm 让你的生活变得更轻松——始终记住。因此,你需要通过选择添加为 Phing 构建文件选项来添加单个构建文件。这可以通过从项目视图中右键单击适当的构建文件来实现。

  • 执行:一切准备就绪。当需要时,选择适当的文件,右键单击并选择运行构建文件选项。

以下截图显示了构建文件:

如何做…

因此,PhpStorm 没有让你和软件工程这两个朋友之间有任何隔阂。

一个示例构建文件看起来像以下代码:

<project name="pizzaCookingSystem" default="compressComponents">

  <target name="bundleComponents">
  <echo message="Creating a package directory."/>
  <mkdir dir="./package"/>
  <echo message="Making a list of components to bind together."/>
  <copy file="../Controllers/Dish.php" tofile="package/Dish.php"/>
  <copy file="../Controllers/PizzaDish.php" tofile="package/PizzaDish.php"/>
  <copy file="../Controllers/PizzaDishTest.php" tofile="package/PizzaDishTest.php"/>
  <echo message="Bundling process complete."/>
  </target>

    <target name="compressComponents" depends="bundleComponents">
    <echo message="Compressing Contents of the bundled components."/>
    <zip destfile="package.zip">
      <fileset dir="package" />
    </zip>
  </target>

</project>

它是如何工作的…

构建文件是唯一提供指导给 Phing 的来源。换句话说,Phing 只认为构建文件足够适合接受执行请求。因此,不同的任务只是单个任务的复数形式(没有开玩笑的意思)。所以,不同的任务被记录在不同的构建文件中,以确保结构模块化得到保持。单个任务根据任何给定时间所需的任务执行。

用 Phing 创造奇迹

没有实际用途的艺术是什么?实际用途意味着艺术的实用性。艺术的实用性清楚地表明了解决问题的能力。所以,将 Phing 视为一种艺术,它具有实际用途。由于它具有实际用途,它具有实用性。由于它具有实用性,它清楚地表明它可以为您解决问题。

您还在等什么?

考虑构建问题,无论是常见的还是不常见的,考虑 Phing。最常见的问题是最常见的头痛原因——您团队中的某些开发者可能不知道特定的数据库语言,有些人可能不知道特定于操作系统的命令,有些人可能不值得信任以允许他们处理系统权限;因此,日志文件或临时文件清理任务。

您可以编写 Phing 任务来处理所有这些问题。

您能写一个 Phing 任务来从 SVN 服务器检出文件并在目标服务器上部署它们吗?是的,您可以。

准备中

您需要加载PHP SSH2扩展。在*nix(基于 Debian)环境中,PHP SSH2 扩展以libssh2-php的名称提供。它可以非常容易地通过命令apt-get install libssh2-php下载。

您还需要在您希望部署代码的服务器上添加您的 SSH 公钥(通常是一个以.pub扩展名结尾的文件)。

如何做到这一点…

当您想到 Phing 时,您必须心理上准备好处理 XML 的严格语法。因此,您需要根据 Phing 的规则编写一些 XML 代码来:

  1. 根据 Subversion 修订号创建一个更改列表,并将其保存到文件中。

  2. 通过读取步骤 1 中创建的文件,将更改的文件导出到您的本地服务器。

  3. 将导出的文件部署到服务器上。

这就像看起来那么简单。所以,您可能会做以下类似的事情:

<project name="SvnDeploy" default="prepareFilesForUpload">
<target name="svnLogin">
<property name="svnUrl" value="http://www.somerepositoryurl/somerepopath"/>
<property name="svnUsername" value="you"/>
<property name="svnPassword" value="you@the-rep0s"/>
<property name="svnCodebaseName" value="name-of-code-base"/>
</target>

<target name="takeDiff" depends="svnLogin">
<propertyprompt promptText="Enter the starting revision number" propertyName="startRev" defaultValue="1"/>
<propertyprompt promptText="Enter the ending revision number (optional)" defaultValue="HEAD" propertyName="endRev" />
<exec command="svn diff ${svnUrl}@${startRev} ${svnUrl}@${endRev} --summarize --xml" output="filelist.${startRev}.${endRev}" />
</target>
<target name="prepareFilesForUpload" depends="takeDiff">
<loadfile property="listOfFiles" file="filelist.${startRev}.${endRev}" />
<property name="directoryName" value="uploads-${startRev}-${endRev}" />
<mkdir dir="${directoryName}" />
<xmlproperty file="filelist.${startRev}.${endRev}" collapseAttributes="true"/>
<foreach delimiter="," list="${diff.paths.path}" param="file" target="exportFilesToLocal" />
</target>
<target name="exportFilesToLocal">
<php expression="str_replace('${svnUrl}/${svnCodebaseName}', '', '${file}');" returnProperty="filePath" />
<if>
<not>
<equals arg1="${filePath}" arg2=""/>
</not>
<then>
<echo message="Exporting file: ${filePath} " />
<php expression="preg_replace('/([a-z0-9-_\.])+\.([a-z])+/i', '', '${filePath}')" returnProperty="fileWithDir"/>
<echo message="Creating dir: ${fileWithDir} " />
<exec command="mkdir -p ${directoryName}/${fileWithDir}" />
<exec command="svn export ${file} ${directoryName}/${filePath} -- force" />
<phingcall target="deployFiles" />
</then>
</if>
</target>

<target name="deployFiles" depends="serverLogin">
<exec command="scp -r ${directoryName}/* ${serverUsername}@${serverUrl}:${serverDeploymentPath}/" checkreturn="true"/>
</target>

<target name="serverLogin">
<property name="serverUrl" value="localhost" />
<property name="serverUsername" value="ankur" />
<property name="serverDeploymentPath" value="/home/techie/Desktop/deployment/" />
</target>

</project>

重型 XML 代码!您被鼓励勇敢地打开引擎盖,看看里面发生了什么。

它是如何工作的…

属性提示是 Phing 在执行期间请求用户输入的方式。您想要显示的消息应写入promptText属性。稍后可以通过在propertyName属性中指定的名称访问输入值。如果您想设置一个默认值作为后备值,以防用户没有输入值,您需要设置默认值属性的值。

Exec 是 Phing 执行命令的方式。如果命令生成了您想在代码的另一个地方使用的输出,您需要指定一个名称,该名称将成为此输出的参考点。

Phing 允许您使用此 loadfile 标签加载文件的 内容。您需要在文件属性中指定文件的路径(绝对路径或相对路径)。此文件的引用名称写在 property 属性内:

<foreach delimiter="A"list="${listOfFiles}"
param="file" target="exportFilesToLocal" />

您可以使用 foreach 标签迭代某个条件。delimiter 属性分隔使用 list 属性指定的输入值。循环中的单个元素可以通过 param 属性中指定的值访问。target 属性表示在循环内要重复执行的目标。请看以下代码:

<mkdir dir="${directoryName}" />

还有更多...

如果您编写了 mkdir 标签并指定要创建的目录的名称在 dir 属性中,Phing 可以创建一个新的目录。如果目录已存在,Phing 将保持沉默,不会产生关于目录的消息——您需要自己小心。您可以使用 phingcall 标签调用构建文件中的任意目标,并在 target 属性中指定目标名称。

所以,奶奶又对了。您使用小而简单的对象创建了一个更大、更复杂的目标。始终记住她的价值观。

使用 Phing 构建视图

PhpStorm 就是如此。PhpStorm 很好。PhpStorm 不歧视。为每个提供的重要工具都提供了工具窗口。Phing 也是如此。因此,您可以了解 Phing 可以做什么。

如何操作...

您可以在 视图 | 工具窗口 | Phing 构建窗口 中访问 Phing 构建视图。Phing 视图提供了对 Phing 相关操作有用的功能。因此,您可以:

  • 添加新的构建文件以执行:您可能已经在其他编辑器中编写了 Phing 构建文件或从另一个人那里获得了这些文件。您可以将这些文件作为构建文件添加到 PhpStorm 中。要添加文件,请点击 + 按钮。

  • 删除现有的构建文件:如果您觉得您已添加了错误的构建文件版本,您总是可以从错误中恢复。您可以通过点击 按钮从项目中删除构建文件。您也可以使用键盘上的 Delete 键。

  • 运行构建文件:如果您觉得所有目标都已正确编写,您可以通过执行构建文件来执行此操作。要这样做,您需要选择一个构建文件并点击绿色的 运行 按钮。

  • 应用目标隐藏设置:在 Phing 视图中,您可以获得对单个构建文件及其内部编写的目标的综合视图。因此,您可以通过选择目标、访问右键单击上下文菜单并点击 标记为隐藏 来隐藏一个目标。当您选择位于 运行 按钮旁边的此选项时,将应用隐藏设置。

  • 全部展开:您可以将所有构建文件展开以显示每个构建文件的(未隐藏的)所有目标。要使用的快捷键是Ctrl + (数字键盘) +

  • 全部折叠:您可以将构建文件折叠以仅显示构建文件而不是目标。相同的快捷键是Ctrl + (数字键盘) -

  • 设置:您可以通过 Phing 为任务的执行进行设置。设置窗口可以通过 Phing 视图内的快捷键Alt + Enter访问。在设置窗口中,您有权力做出改变。以下是您如何做到这一点的方法:

    • 您可以获得一个指向 Phing 可执行选项的路径,在那里您可以设置读取或更新项目 Phing 可执行路径。

    • 然后,还有命令行选项允许您传递某些选项,例如-l(列出目标)和-debug(设置调试模式)。

    • 您可以以键值对的形式设置属性。PhpStorm 为您提供从可用宏或预制的占位符列表中进行选择的选择。您可以通过选择或取消选择隐藏目标复选框来选择要隐藏或取消隐藏的目标。

此外,所有在 PhpStorm 中可用的视图设置都提供在这里。选项包括:您可以为视图设置显示模式,选择固定、停靠、浮动和分割中的一种方式。您可以将窗口移动到屏幕上的四个区域之一(顶部、左侧、底部和右侧);调整窗口到所需大小,完全隐藏视图,等等。

注意

您创建的 Phing 应用程序特定设置必须为添加到 PhpStorm 的每个构建文件单独创建。

它是如何工作的…

在这里,理解 Phing 设置的工作方式非常重要。PhpStorm 充当它所执行的任何工具的代理——它始终为目标工具创建包装器(类)。因此,当您尝试设置命令行选项或添加属性时,您是在告诉这个代理应用程序记住,每当发出 Phing 命令时,命令行选项文本框中的参数都应该被执行。换句话说,您将参数传递给 PhpStorm 代理应用程序,该应用程序反过来执行相同的旧 Phing 命令。您设置的属性将按原样用于构建文件。因此,当您设置属性时,您确实是在使属性持续到您自己不删除它为止。

第八章. 烹饪库插件

在本章中,我们将涵盖以下主题:

  • 创建库插件

  • 精炼插件

  • 使用 PhpStorm 配置插件

  • 插件的代码提示

简介

想象一个世界,程序员就像你一样,只是喜欢编写代码。这个世界看起来很愉快,完美,首先非常适合你。然而,事实并非如此。在世界上,什么能让程序员比任何事情都更快乐和满足呢?那就是应用程序最终到达最终用户的情况。然而,如果程序员只是喜欢编写他们的代码,那么谁会确保代码被交付给最终用户呢?

最终用户可以是任何人——一个新手用户、专业用户,甚至是另一个程序员。所以,无论在什么情况下,场景或最终用户,作为程序员的你都必须小心谨慎,确保你编写的代码是(可)重用的。在你的整个软件工程生涯中,你被告知过,你也会被告知不要重复造轮子。如果你想使这个枯燥的原则保持活力,你必须让你的代码可使用和可重用。

另一个用例!假设你被要求在 PHP 中开发一个应用程序编程接口(API)。所以你手头的任务是编写代码。但对你来说还有一个(未说出的)任务是确保你编写的代码可以以最小的麻烦被包含。实现这一壮举的一个快速解决方案是将你的应用程序打包成一个存档,这样存档本身就可以在任何需要的地方被包含。请再次阅读!你需要有一个类似捆绑包的实体,你可以将其传递给测试团队以验证和确认。一个明智的程序员会建议使用 Phing 来一起构建文件。然而,这种情况的难点在于 Phing 会做你要求它做的事情。然而,你真的知道你要做什么吗?

你没有看错,你需要创建一个存档。这次,我们使用 PHP 存档,或者叫 phar,就像行业里称呼的那样(www.php.net/manual/en/book.phar.php)。Phar 对你来说不应该陌生。在你的软件工程生涯中,你一定多次使用过 phar。某个时候,一个 PhpStorm 食谱的作者可能指导过你如何获取 phar 并将其包含在 PhpStorm 库路径中。你能回忆起你曾经多么容易地找到在项目中添加 PHP 功能这个任务吗?如果可以,那么现在是时候转换角色了——从 phar 用户到 phar 创建者。如果不能,那么现在是学习如何创建 phars 的好时机。

注意

Phar 是 PHP 创建的存档文件。和其他存档一样,phar 也包含了许多文件和目录。为了能在你的应用程序代码中使用 phar,你只需要在代码中包含或引入 phar。就是这样!Phar 会表现得就像你包含了(或引入了)一个普通的 PHP 类。你将能够使用在 phar 内部声明的类、对应的方法和成员变量(当然,会尊重访问限定符)。

然而,拥有 PhpStorm 可以帮助你很多。你还可以将 phar 包含在项目的包含路径中,以便特定项目能够使用 phar 提供的功能。如果你需要将 PHP 功能提供给开发机器上的所有项目,考虑将 phar 添加到全局包含路径。

PHP 编程一直很有趣。然而,既然你是团队中的资深成员,强烈建议你在享受工作乐趣的同时,还要关注工作的实用性。

创建库插件

你有没有想过是什么构成了一个库?库就像一个图书库一样,是一个有用方法的集合。同样,应用程序库包含了许多有用的方法和元素。重点在于“有用”这个词,强调在库中不保留冗余的方法和元素的重要性。一段冗余的代码需要文档。当公司投入资源(本质上就是金钱)时,它永远不会希望拥有使用频率较低的实体。这是为什么?经济学的原则——任何公司的首要目标是最大化利润。无论如何!

准备工作

然而,不必担心,你不需要成为经济学诺贝尔奖得主才能停止在库中添加冗余元素。只需保持冷静,保持明智。制作插件涉及许多工程决策。其中一些决策可以是:

  • 决定让你编写库的原因:你不会经常有创建库的任务。库是一系列你经常需要的方法的集合。因此,决定哪些方法是必需的,需要一定的成熟度。

  • 提前规划:由于库是一种经常使用而很少修改的东西,你不会经常发布版本。由于版本发布得很少,如果在创建库的过程中出现了一个不正确的计划,那么你可能会很晚才发现你没有很大的错误空间。

  • 制作/重用决策:你必须决定所需的库是否可以通过重用他人的代码,甚至是你为过去的项目创建的代码来构建。记住,你需要对此有敏锐的记忆。另一个需要决定的选项是是否从头开始创建一个库。

因此,本质上,所有规则都是为了方便创建包含 PHP 代码的phar。准备好享受这次旅程吧!

如何做到这一点...

  1. 选择一个包含你想要包含在插件中的代码的目录。既然你一直在尝试制作披萨,你可以假设一个用例,即最终用户需要一个制作披萨的算法。在那里,你有需求!

  2. 创建一个名为src的目录,其中将包含源 PHP 脚本。这将是库的源。

  3. 创建一个名为build的目录,它将包含目标库,如下面的截图所示。这就是你一直渴望的库。如何操作…

  4. 你可能需要在php.ini文件中进行一些更改。要找出你的系统使用哪个php.ini,你可以在 PhpStorm 中输入php-ini(你还记得可以通过键盘快捷键Ctrl + Shift + X访问的命令窗口吗?)。你需要添加行phar.readonly=0以启用使用 PHP 创建 phar。

  5. 你需要为库定义一个入口点。为什么需要这样做?这是 phar 的行为方式。默认情况下必须有一个index.php文件。你需要将它放在src(或源)目录的顶层。至少,它需要包含一个文件,该文件将提供对库中所需类的访问(当然,你可以将index.php的名称更改为另一个file.php,并使其作为入口点)。

    在当前场景中,你需要包含PizzaDish.php文件,这样你才能再次制作披萨——这次是通过库。所以,考虑到 PHP 代码,你将编写如下内容:

    <?php
    require_once "PizzaDish.php";
    ?>
    
  6. 由于 phar 是 PHP 功能,你需要编写代码来创建 phar 包。你将编写如下内容:

    <?php
    $srcRoot = "src";
    $buildRoot = "build";
    $phar = new Phar ($buildRoot. "/pizza.phar", FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::KEY_AS_FILENAME, "pizza.phar");
    $phar->startBuffering ();
    $phar->buildFromDirectory ($srcRoot);
    $phar->stopBuffering ();
    ?>
    

完成这些后,你可以坐下来,感到高兴,因为你已经创建了一个新的插件,你可以轻松地将其传递给测试和质量保证团队。

它是如何工作的…

是时候准备螺丝钉、润滑油和油腻的工作服了!

你可以看到你并没有做什么特别的事情:你只是写了一些非常简单和自然的 PHP 代码来生成一个可以作为插件使用的存档。你创建了目录来分别存放源文件和构建文件。这一步不是强制性的,但它确保了你的工作区域保持整洁。

index.php文件作为 phar 的入口点。因此,当你包含一个功能时,你需要涉及对该功能的引用。这就是你包含PizzaDish.php时所做的:

$phar = new Phar($buildRoot . "/pizza.phar", FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::KEY_AS_FILENAME, "pizza.phar");

当你编写这段代码时,你正在初始化创建 phar 的功能,它接受预期插件的名称(第一个参数),传递给父类RecursiveDirectoryIterator的标志(第二个参数),以及将作为其调用名称的存档名称。因此,你将创建一个库,其文件名为pizza.phar,当你通过phar://流访问时,它将被称为pizza.phar

你需要开始缓冲以启动创建存档的过程。缓冲是将数据写入磁盘直到缓冲停止的过程。这是通过$phar->startBuffering();来完成的。

当你编写以下代码时,目录内的源文件被包含在你创建的插件中:

$phar->buildFromDirectory($srcRoot);

将文件包含到存档中的过程会一直持续到你停止输出缓冲。你需要停止缓冲以完成将更改写入磁盘的过程。你编写的存档在你停止缓冲之前是不可见的。这是通过$phar->stopBuffering();完成的。

一旦你停止输出缓冲,输出(即存档文件)将显示给你。如何?以存档本身的形式!简单,不是吗?

插件的精炼

旁边有一个插件确实会鼓励你。然而,如果不对手头的插件应用软件工程原则,这种鼓励可能会导致一些严重的后果。这可能会让你成为一个退居二线的工程师!

软件工程是你在做任何事情时都不容易忘记的实体。你需要验证你创建的产品(这里,插件)是否工作正常。现在,这个“正确”有一个非常广泛的意义。简单来说,你只需要检查你创建的插件是否执行了预期的操作。另一方面是验证。在检查了预期的操作后,你需要检查执行的操作是否正确。这一点特别有用,因为实际的测试是根据这一现象在插件上进行的。

如何做…

你需要采取两个动作。两者都是强制性的。第一个是验证部分。你需要验证披萨烹饪插件是否工作。为此,你需要:

  1. 创建一个新的 PHP 文件。

  2. 在其中包含(或要求)你创建的插件。

  3. 按照以下截图所示运行此文件。

    如果运行过程如所示完成,这意味着你的披萨正在被烹饪。

    如何做…

现在是验证部分。你可能需要验证你正在烹饪的实际上是披萨,否则你可能会破坏你的味蕾。为了验证这一点,这是一个相当模糊的步骤序列,并且可能会有不同的版本。步骤可以是:

  1. 检查插件中的类是否可以自由访问。你需要创建对象的新实例。因此,像$pizza = new PizzaDish('Mushroom', 'Dish')这样的操作不应该产生错误。你应该能够像使用本地创建的类一样使用该对象和外部类中的成员。同样,像echo $pizza->getDishName()这样的操作不应该创建关于此函数不可用的错误,并且应该正确执行预期的活动。

  2. 如果插件中出现了你认为不符合业务要求的问题,你需要(显然)快速修复它。所以,你可能需要再次遵循几个步骤:

    1. src目录中,找到文件(这里PizzaDish.php)。

    2. 识别创建错误(或行为不当)的行。

    3. 进行适当的更改。

    4. 使用更改后的源代码重新创建 phar。你可能想回顾一下“创建库插件”的配方。

  3. 重复步骤 1-3,直到插件开始以预期的行为运行。

无论你做什么,你只需要有一个插件的精炼版本。

它是如何工作的...

验证过程的工作原理相当直观易懂。产品的验证检查你创建的插件是否实际上作为一个插件在工作。因此,你检查在作为系统使用插件的过程中可能出现的错误和问题。这就像说,“伙计,检查一下插件是否在工作”。你能想象是谁说的吗?是一个程序员对他的同行程序员说的!

验证过程需要理解。当你创建一个插件时,你不知道哪个代理会使用它——它可能是一个命令行用户、一个 IDE 或另一个更大的插件。因此,你需要确保你编写的插件是可用的。因此,当你创建一个新的对象时,你检查你打算在插件中提供的类是否存在。当你调用一个方法时,你检查插件内部定义的方法是否可访问,而且,没有不适当的访问修饰符限制你使用该方法。

插件的验证过程相当循环。由于确保插件正常工作是你的责任,你需要重复验证步骤,直到质量保证团队对插件完全满意。在这个过程中,如果你发现错误,你将不得不回到源代码中修复问题,并重新构建整个插件。

因此,这个过程对你来说继续进行。你编写代码。代码被测试。你修正代码。代码被测试。代码被测试。你创建一个插件。插件被测试。你回到正确的代码,并从那个点继续这个过程。循环,不是吗?

使用 PhpStorm 配置插件

当说到有一个插件时,可以假设必须有一个使用该插件的用户。既然你是 PhpStorm 的爱好者,你可以安全地假设 PhpStorm 可以是(其中之一)可能的插件用户。因此,你需要充当库插件的伪接收者并尝试使用库。通过配置,可以理解为在项目结构中进行必要的调整,以便可以使用库来为项目添加功能。你看到了,这是可重用性的古老实践在发挥作用。

与库插件相关的主要优势是将其包含到项目中的便利性。你只需利用这个优势。

如何做到这一点...

要使用 PhpStorm 配置插件,需要遵循以下步骤:

  1. 从你想要的任何来源获取 phar。

  2. 在你的项目中创建一个具有适当且描述性的目录。

  3. 可以通过require(_once) 'phar://name-of-phar.phar';非常容易地使用插件。

完成了!如此简单——完全不像它看起来那样。这是 PHP 释放的力量。

还有更多...

然而,如果你认为你想用这个库做更多的事情,并且对通过调整内部类和/或包进行开发更感兴趣,你可能需要特别选择某些类。这是通过require_once 'phar://pizza.phar/Dish.php';来完成的。

它是如何工作的…

创建一个目录来存放库插件并不是什么高深的技术。这只是为了方便遵守软件工程规范。这里提到的开发者或插件用户。因此,当你创建一个新的目录时,你正在工作的项目的代码库保持模块化。所以,当你需要更改这个库时,你知道该去哪里。同样,当你需要从代码库中删除这个库时,你也知道该去哪里。如果你被问到何时需要添加一个具有类似功能的库或某些依赖项,你知道去哪里吗?

你使用库的方式取决于场景。回想一下,库插件包含两个文件:PizzaDish.phpDish.php。如果你想使用基本功能——通过添加一些简单的配料和食材来烤披萨——整个 phar 的使用就足够了。如果你想使用特定的功能,指定相对于 phar(在 phar 内部)的文件名就足够了。

由于 phar 据说表现得和 PHP 文件一样,当你包含 phar 时,提示也开始。因此,当你写下phar://pizza.phar/并按下Ctrl + Space时,会显示给你一个包含在 phar 内部的所有文件的列表。你可以像使用常规 PHP 文件一样从列表中选择一个。

插件的代码提示

使用你创建的插件的 IDE 的实际效用现在显现出来了。开发者们普遍相信,IDE 无论在什么情况下都能提供自动补全功能。然而,在同一群开发者中,知道 IDE 如何提供自动补全功能的人却非常罕见。奶奶总是说“无知无回报”。没错!无知无回报(言外之意)。

可能会有一个疑问出现在你的脑海中。为什么你需要使用自动补全功能呢?这个答案可能不是外交辞令,但它是真实的。在大多数情况下,开发者们足够无知,以至于不会为他们的代码编写文档。因此,自动补全和/或代码提示成为了你提供的代码用户的救星。既然你自己也是程序员,你很容易就能理解使用代码提示功能的便捷性。

在当前上下文中,你需要有类似的设置,这样 PhpStorm 才能显示文档、方法使用和对于潜在的插件用户来说是必要的信息。

准备工作

为插件启用代码提示是一个单行操作。如果你真的想为 PhpStorm 配置代码提示,你需要更新 PhpStorm 尊重的包含路径。更新包含路径是通过打开项目视图并将 phar 的位置添加到项目的库列表中完成的。

如何做到这一点…

步骤如下:

  1. 选择项目视图(Alt + 1)。

  2. 找到外部库目录。

  3. F4

  4. 提供插件所在目录的位置。

  5. 点击应用并按确定

完成!深呼吸,并在需要为此插件激活代码提示时按Ctrl + Space。PhpStorm 再次为你服务!

它是如何工作的…

PhpStorm 会在项目可用的包含路径中进行查找,并提供当前上下文中可用的类和方法列表。系统范围内的包含路径(/usr/share/php/usr/share/pear等)也会被查找。因此,当你将 phar 添加到包含路径时,PhpStorm 会得到一个额外的查找路径。

因此,在 phar 中可用的方法和类(你在index.php中包含的)将可用于代码提示。代码提示过程涵盖了文档、成员方法、成员变量以及你设计为可用的任何其他内容。

注意

值得注意的是,当你将库插件添加到包含路径中时,你将以与其他在包含路径中声明的类和库中可用的方法相同的方式开始获得提示,但有一个需要注意的区别。当你将库位置添加到包含路径中时,PhpStorm 能够为你提供代码提示。如果你想使用方法,你将无法做到。另一方面,当你需要使用插件,并且你require_once)它时,代码提示也是可用的,但这次对当前脚本有效。

那么,区别在哪里呢?区别在于插件及其方法的使用和可用性。

总结一下,如果你想使用插件,你需要使用include(_once)require(_once),并且当你需要代码提示在整个项目中可用时,你需要将插件的位置添加到 PhpStorm 的包含路径中。

第九章。代码质量分析

在本章中,我们将涵盖以下主题:

  • 杂乱检测器和 PhpStorm

  • 代码嗅探器和 PhpStorm

  • 定位代码重复

  • 代码格式化和排列

简介

工程之美。工程之美在于它在执行甚至最简单的任务时,不留任何石头,不遗漏任何路径。对于普通人来说可能显得过于微不足道——但它们也被工程所关注;软件工程,具体而言。

你会同意时间会使人成熟。你还记得当你作为一个新手软件工程师,面对一个需要解决的问题时,你的态度是怎样的吗?你开始使用你对实际代码的幼稚认识来制定计划。多么幼稚啊?随着时间的推移,你开始积累经验,你开始使用类似草稿纸的东西,首先使用原始的草图技术来规划,以可视化算法的流程。这就是你开始感觉到需要工程图的时候。你开始学习 UML——所有建模语言的母亲,也是软件工程的基础。

时间一直在带你经历生活的艰难课程。在适当的时候,你意识到如果不遵循工程原则,前进起来很容易,但道路是单方面的,单向的。一旦你需要回头纠正你作为人类所犯的错误,这个行动可能会让你陷入一种无人遵守重力法则的状态。所以,你和软件工程成为了朋友,生活变得容易多了。

到目前为止,一切顺利。

如果说你可以更多地了解你的亲密朋友——软件工程——这并不错误或不恰当。软件工程不仅帮助你设计系统时保持道德,还跟踪你编写的代码。例如,你编写的代码行数可以作为一个衡量软件成本的指标(考虑到每行代码都花费一定数量的金钱)。你代码中的变量名需要遵循严格的标准。为什么?一旦需要修改,只有人类才需要逐行检查代码。由于变化是不可避免的,这个事件发生的概率很高。

总结来说,软件工程为你提供了系统来分析你的软件应用的这一方面。这个过程被称为代码质量保证,因为你可以创建出可读且易于维护的代码。帮助你实现这一里程碑的系统被称为PHP Mess DetectorPHPMD)和PHP Code SnifferPHPCS)。PHPMD 实际上会识别和检查团队成员在代码库中造成的混乱,并提供警告、错误信息和指示,不仅可以帮助清理混乱的代码,还试图保持代码库的整洁。Code Sniffer 充当嗅探犬,每当它检测到代码库中的潜在错误时就会发出警报。并不是说你的眼睛和大脑无法检测代码中的简单错误,但在开发阶段,作为一位疲惫的软件工程师,你可能会犯下非常简单的错误。随着时间的推移,这些错误会逐渐演变成一个神秘的 bug,可能非常难以破解。PHPCS 在遏制此类错误方面非常有帮助。

一个显而易见的问题:PhpStorm 在这个场景中在哪里?答案是 PhpStorm 始终可供你使用。它是如何做到的呢?提到的两个系统与 PhpStorm 结合使用,以破坏试图潜入开发阶段的 bug,并长时间甚至长时间地困扰你。这是对你带宽的浪费,从而降低了士气——你的经理不会轻易让你离开,直到你能够调试你的应用程序。

混乱探测器和 PhpStorm

PhpStorm 是你的忠实勤奋的奴隶。它确保你的任何努力都不会被归类为粗糙或不经过工程化。它是如何做到的呢?它为你提供了集成系统的设施,这些设施反过来帮助你让努力达到工程化的成熟度。你一定很想知道这里所说的系统是哪一个。所以,你可以伸出双手,为被称为 PHPMD 的混乱探测器鼓掌。确实是一个简单的缩写。并不是说 PhpStorm 剥夺了你从代码中清除混乱的应有赞誉,但是的,PhpStorm 为你提供了查找适当版本、下载、集成,然后开始规划要做什么的便利。然后呢?然后呢?只需坐下来,让 PhpStorm 和混乱探测器协作,为你完成任务。

准备工作

您需要了解 PHPMD 的最新(且稳定)版本信息。您可以通过任何流行的搜索引擎在互联网上简单地搜索它。官方网站(phpmd.org/)提供了有关可用下载方法的信息。由于您对 PHP 存档有很好的品味,您可以从 URL static.phpmd.org/php/1.4.1/phpmd.phar(这是撰写本文时可用的最新 phar)获取 phar(这将是可执行文件)。就像其他存档一样,您不需要采取任何其他行动——只有这个下载就足够了。

当您谈论可执行文件时,由于*nix系统将所有从外部来源下载的文件视为只读,检查 phar 的访问权限就是您的责任。在大多数情况下,下载的文件只读权限只是为了安全起见。您需要足够聪明,将权限降级以允许适当的存档访问。在*nix系统中,有一个可用的命令chmod,您可以使用它来在指定的文件或文件夹上玩转访问权限。因此(使用chmod),您可能可以将此存档的权限字符串设置为766

如何操作...

现在是重要的部分——您需要告诉 PhpStorm 关于 PHPMD 的信息。这是一项您确实需要确保已设置的配置。原因在于 PhpStorm 的开始是为了让 PhpStorm 知道它有一个新成员,因此需要相应地采取适当的行动。执行以下步骤:

  1. 您需要选择文件 | 设置 | PHP | Mess Detector并设置您刚刚下载的 phar 路径(或者可能从朋友那里借来的),如下面的截图所示:如何操作…

  2. 验证您所做的工作。不用担心,PhpStorm 会帮助您,因为有一个通过验证按钮检查配置是否正确的功能。如果您一切都做得正确,您将收到来自 PhpStorm 的绿色信号,指示软件的名称(PHPMD)、作者和版本号,如下面的截图所示:如何操作…

  3. 您需要在 PhpStorm 中配置 PHPMD 可用的选项。设置可在文件 | 设置 | 检查中找到。

  4. 打开检查功能。

  5. 通过在文件 | 设置 | 检查中打开设置向导并选择PHP Mess Detector验证旁边的复选框来配置检查。

  6. 存在一系列预定义的规则;您需要根据您的需求选择其中一些或全部。因此,您可以选择一个或所有代码验证规则,然后继续编写代码。就是这样。下面的截图显示了检查页面:如何操作…

    PHPMD 将在后台继续工作,并在你编写代码时继续显示错误和警告。通知是根据你配置的方式进行分类的。

  7. 要配置通知,你需要选择单个规则,并根据需要更改颜色、字体等。以下截图显示了在严重性编辑器页面上的“编辑设置\颜色和字体”标签页的外观:如何操作…

它是如何工作的…

让 PHPMD 运行起来并不困难。你只需要做一些设置,然后继续做你最喜欢的工作——编写代码。然而,由于你是一名工程师,你应该渴望了解在引擎盖下究竟发生了什么,让你能够继续前进。

默认情况下,PHPMD 遵循一些规则。这些规则是在考虑到软件工程原则的同时制定的。有一些规则需要检查:

  • 代码大小规则:时不时会有事件发生,需要你检查代码的大小。重要的是要说明,你不仅是为了写代码而写,而且是为了以后阅读和维护它。一个非常重要的因素是代码的大小及其相关的复杂性。

  • 圈复杂度:理论上,需要绘制一个流程图来表示所讨论的算法,然后计算边、节点和出口点,最后通过边数减去节点数再加上流程图中的出口点数得到结果。

    PHPMD 在其实现中抽象了这些细节。它考虑了决策点的数量,例如循环结构——if、for、while、case 等,并计算复杂度为代码中的决策点数加 1(一个)作为方法的入口点。

  • N 路径复杂度:然后,还有 N 路径复杂度,这是 PHPMD 负责的。N 路径是代码中可能的结果数量。它可以是在代码产生输出的情况下。因此,PHPMD 决定,对于健康的代码,200 是一个合理的限制。这意味着如果你的方法是高质量的代码,你的代码(方法)可以有最多 200 个结果。

  • 过度方法长度规则:PHPMD 通过计算方法中的代码行数来限制方法的长度。这被称为过度方法长度规则。因此,如果一个方法的代码行数超过 100 行,那么这个方法违反了这一限制,PHPMD 会以警告或你配置的方式向你指示:

    • 如果你类中的代码行数超过 1,000 行,你需要重构你编写的类。谁说的?这是 PHPMD 过度类长度限制。

    • 如果声明的参数数量超过 10 个,PHPMD 会通知你将参数数量减少到 10 个以下。然后你可以尝试传递一个包含类似参数的单个对象。这个规则被称为过度参数列表限制。

    • 如果一个类中有太多的公共成员,PHPMD 将其视为低质量代码,并通过 PhpStorm 向你报告。过多的因素设置为默认值 45,超过这个值,PHPMD 开始将你的代码视为不良代码。

    • 拥有太多的私有或受保护的成员也不被视为良好。如果有超过 15 个这样的成员或字段(更技术性的说法),PHPMD 会通知你。你需要重构你的类以减少字段数量。为什么不尝试使用组合?这是“”关系...还记得吗?

    • 如果你在一个类中写了太多的方法,要小心。PHPMD 将将其视为低质量代码,并指出你需要重构类以减少类中的方法数量。阈值是 10。

  • 有争议的规则:当以下情况发生时,PHPMD 将代码视为低质量代码:

    • 你可以直接访问一个超级全局数组,而不将其封装在某个对象中。

    • 你没有使用驼峰式命名法来命名类、类成员以及你在代码中使用的任何变量。

  • 设计规则:当用 PHP 编写的代码满足以下条件时,将被视为不良代码:

    • 你的代码中在常规代码中有退出点,例如没有异常/错误处理行的退出点。

    • 你喜欢在代码中使用eval

    • 你觉得在代码中使用goto很有趣。

    • 你创建了一个类过多的子类。对于 PHPMD 来说,15 是阈值。

    • 你创建了一个类层次结构,其中一个类继承了超过六个父类。

  • 命名规则:当 PHPMD 发现以下情况时,也会皱眉并指出代码不良:

    • 变量名过长或过短。当长度超过 20 个字符时,名称过长;当长度小于三个字符时,名称过短。真的非常短!

    • 方法名过短,难以理解。当长度小于三个字符时,名称过短。

    • 构造函数使用了封装类的名称。

    • 类中的常量以小写字母书写,单词之间用下划线(_)分隔。

  • 未使用代码规则:PHPMD 并不重视代码的未使用状态。根据 PHPMD,代码不良的情况包括:

    • 你声明了,并/或为局部变量或私有字段赋值。

    • 你声明并/或定义了一个方法,但没有使用它。

    • 你声明了一个方法的形式参数,但没有使用它。

    这里是 PHPMD 在行动中的样子。你可以看到当你继续编写代码时,PHPMD 如何提供错误和警告:

    如何工作…

还有更多…

如果你认为预定义的规则集不足以支持你的需求,你可以将你自己版本的规则集文件添加到 PhpStorm 中。你需要做的就是创建一个新的 XML 文件,给它一个合理的名字,并让 PhpStorm 将其合并,如下面的截图所示:

还有更多…

你的规则集文件看起来有点像以下代码:

<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="test-ruleset"

xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>A custom ruleset – You can do wonders with this.
</description>
<rule ref="rulesets/codesize.xml/TooManyFields"/>
</ruleset>

实际的检测是在你编写<rule ref="rulesets/codesize.xml/TooManyFields"/>时进行的,因为正是这一行选择了为 PHPMD 开启哪个选项。其他在开头编写的行——你不需要费脑筋——只是构成了基本框架部分。故事最好的部分是,你不需要记住这些行:你只需从这里复制这些行并将其粘贴到任何你想要的ruleset.xml中。你需要记住的唯一事情是你希望应用的规则的准确名称。

代码嗅探器和 PhpStorm

你注意到为什么防御人员会使用嗅探犬吗?没有?嗅探犬的目的是嗅探周围物品并检测这些物品中是否存在任何非法物品。你可能想知道狗是如何决定哪个是非法的,哪个是合法的,即使它做到了,它又是如何通知人类关于物品有效性的。狗只知道如何吠叫:它会在两种情况下吠叫,无论是高兴还是悲伤。不管怎样,问题仍然存在。狗是如何知道非法物品的?

答案是直接、简短和简洁的:狗是被配置或训练来做这件事的。

你有 PhpStorm 吗?你一直在用它来满足你的编程需求,对吧?你可以用类似的方式使用 PhpStorm 来嗅探你的代码,并在代码包含一些编码标准违规时通知你。为 PhpStorm 提供此功能的是 PHPCS 或 PHP Code Sniffer。

PHP Code Sniffer 是一个 PHP5 脚本,它将 PHP、JavaScript 和 CSS 文件进行标记化,以检测违反定义的编码标准。它是一个确保你的代码保持清洁和一致性的基本开发工具。它还可以帮助防止开发者犯下的常见语义错误。

PHPCS 是一个用 PHP 编写的应用程序,可以用预定义或自定义的编码规则集进行配置。它检测可能的不一致和不整洁的代码,因此不允许常见的语义错误在生产代码中通过。

准备就绪

在你甚至计划开始代码嗅探之前,你需要下载 PHPCS 为.tgz格式,这样你就可以在你的本地系统中准备好安装文件。该文件可以从download.pear.php.net/package/PHP_CodeSniffer-2.0.0a2.tgz下载。之后,就是安装过程。在 PhpStorm 中安装 PHPCS 相当简单(和其他操作一样简单)。你需要执行以下步骤:

  1. 将你下载的 tgz 文件内容提取到你的开发机器上的一个方便位置——通常是你用 PhpStorm 进行实验的电脑。

  2. 在提取的目录中,找到phpcs文件,这是一个用 PHP 编写的脚本。这很可能是脚本目录中。

  3. 检查设置在可执行文件上的权限是否足够允许 PhpStorm 使用它。如果你发现可疑之处,请将此 PHPCS 文件的权限设置为755

  4. 执行最重要的步骤。你需要告诉 PhpStorm 有 PHPCS 可用。为此,你需要选择文件 | 设置 | 代码检查器,并设置此 PHPCS 的路径,如以下截图所示:准备就绪

  5. 验证设置是否已正确设置,并且一切如截图所示正常:准备就绪

如何操作…

在使用 PhpStorm 配置了代码检查器系统后,你不必担心 PHPCS 如何工作。它只是默认的检查系统在后台工作。然而,你需要将其打开。可以通过选择 PHPCS 可用的检查选项来启动代码检查过程:

  1. 在右下角,有一个可用的检查图标。你需要点击它,然后点击可用的配置检查选项,或者可以通过选择文件 | 设置 | 检查来获取相同的选项。

  2. 你需要选择 PHP 检查树,并在其中选择PHP 代码检查器验证选项。

  3. 在编码标准旁边有一个下拉菜单。你需要选择其中一个可用的值。

  4. 如果你向 PHPCS 添加更多值,你需要刷新可用的标准列表。刷新操作会通过一个消息得到确认,如以下截图所示:如何操作…

  5. 完成这些后,你现在可以专注于为你的组织编写业务逻辑。PHPCS 将在后台继续运行,并在你进行时持续显示错误。以下是一个显示错误的截图:如何操作…

它是如何工作的…

PHPCS 的工作原理并不难理解——尤其是对于像你这样的人,你已经熟悉 PHPMD 等系统(以防你不熟悉它。这是个双关语!)。PHPCS 还能理解 XML,并且 PHPCS 还内置或预定义了规则。当你将 PHPCS 与 PhpStorm 集成时,这一点尤为明显。你可以通过下拉菜单中的这些默认值访问可用的编码标准。这个下拉菜单的标签是编码标准:PHPCS 系统遵循这些标准,并在你打开代码时进行检查。

到目前为止,一切顺利。实际的“关键部分”位于 ruleset.xml 文件中。不,这不是由于工程复制粘贴导致的印刷错误!ruleset.xml 文件在创建过程中遵循某些标准。驱动 PHPCS 的规则是:

  • 由于它是 XML 格式,最重要的行是添加 XML 版本:

    <? Xml version="1.0"?>
    
  • 规则集中所有节点的父节点是 ruleset 节点。名称属性使节点在 PhpStorm 中通过名称识别:

    <ruleset name="PHP Code Sniffer Standard">
    
  • 可能有一个描述节点,其中包含正在构建的标准描述:

    <description>A custom coding standard</description>
    
  • 然后是实际的规则。PHPCS 可以接受对他人可能创建的规则的外部引用:

    <rule ref="/path/to/some/persons/ruleset.xml"/>
    
  • 可能有一个包含以 PHP 类层次结构形式存在的代码标准的目录:

    <rule ref="/full/path/to/standard-classes/"/>
    
  • 或者,可能有一个对知名编码标准的引用,例如 PEAR 或 Zend:

    <rule ref="PEAR"/>
    
  • 一些默认标准被包含在以下代码中:

    <rule ref="Generic.Files.LineLength.TooLong">
    <message>Line longer than %s characters; contains %s characters</message>
    
    </rule>
    

    或者,它还可以有以下的代码:

    <rule ref="Generic.File.LineEndings">
      <properties>
        <property name="eolChar" value="\r\n"/>
      </properties>
    </rule>
    

还有更多...

由于标准是以 PHP 类层次结构的形式定义的,因此包含也尊重了ref属性中的层次模式。所以,实际引用的类是位于/path/to/PHP_CodeSniffer/CodeSniffer/Standards/Generic/Sniffs/FilesLineEndingsSniff.php目录下的Generic_Sniffs_Files_LineEndingsSniff类,该类是在 2.0.0a2 版本中定义的。正在尝试设置的类属性是eolChar,它恰好是类的一个公共字符串类型成员。

你可以在pear.php.net/manual/en/package.php.php-codesniffer.annotated-ruleset.php找到示例规则集文件。

定位代码重复项

商业需要资金,资金需要工程,工程需要计划,而计划需要时间。由于商业需要资金,而时间就是金钱,因此商业不希望浪费时间。浪费时间就是浪费金钱,所有(软件)商业都认为花出去的钱就是损失。由于商业节省开支,工程就转向代码复用。然而,客户需要质量——毕竟,客户已经支付了一大笔钱来完成这项工作。这是一个恶性循环。

当工程团队时间紧迫时,面临的挑战始终是确保复制粘贴的任务在控制之下,没有副作用。控制意味着软件能够完成预期的任务。副作用是软件中的重复部分,这可能导致代码行数的增加。

情况似乎很严峻!

在你的编码生涯中,你必须始终记住 PhpStorm——无论你是休闲还是遇到麻烦。PhpStorm 总是为你提供一些东西。这次,PhpStorm 将帮助你摆脱这个恶性循环。有一个功能允许你扫描代码并定位重复代码。

如何做到这一点...

为了有效地在代码中定位重复项,请执行以下步骤:

  1. 你需要从主菜单中选择代码 | 查找重复。你将得到一个弹出窗口,这是你的选择点,如下面的截图所示:如何做到这一点…

  2. 默认选择是整个项目。你有选择在整个项目中查找代码重复项的选项。

  3. 你还可以根据开发周期阶段设置标准来处理文件类型或类别。你可以选择未提交的文件来定位你尚未提交的代码中的重复项。这可以是一个提高代码质量的好主意。

  4. 你可以在编辑器中选择当前打开的文件来定位重复项。PhpStorm 还为你提供了设置自定义重复查找范围的选择:

    • 项目测试文件:当你想要定位为项目创建的测试文件中的重复代码片段时,可以使用此功能。当你有大量的测试用例(具体来说是 PHPUnit 测试用例)时,这会很有用。

    • 打开的文件:当你需要选择编辑器中的打开文件时,PhpStorm 会将重复搜索的范围设置为仅限于打开的文件。

    • 模块:当你想要分析非项目文件,如库或软件开发工具包(SDK)时,PhpStorm 通过允许此选项为你提供便利。

    • 当前文件:当你非常确定只想查看当前打开并正在积极查看的文件时,PhpStorm 为你提供此功能。

    • 选定的文件:当你需要从项目视图中选择几个文件时,PhpStorm 会将重复搜索的范围设置为仅限于选定的文件。

    • 已更改的文件:作为一名经验丰富的专业人士,你可能需要审查其他开发者编写的代码。此选项对于已更改但尚未提交到代码库的文件非常有用。

    • 默认:当你想要在代码库更改的默认更改列表中查找可能的重复项时使用此选项。

    注意

    你可以单独包含或排除重复分析中的测试源。

  5. 代码重复分析设置定义了搜索的敏感性,并设置限制以帮助避免报告每个类似的代码结构。以下截图显示了代码重复分析设置:如何操作…

  6. 你可以将函数、变量和字面量匿名化以节省内存堆。

  7. 你可以指示 PhpStorm 将重复分析设置限制为仅挖掘大于特定大小的代码块。默认大小为 10。

如何工作…

这个问题的答案很诚实!代码重复检测是诚实的,并找出代码中的重复。因此,在你调用重复代码查找器后,它会找到文件中具有重复代码的实例。重复代码块是基于你在设置中指定的过滤条件(请参阅如何操作…部分)找到的,如下面的截图所示:

如何工作…

更多内容...

需要清楚地理解代码重复的概念,以便深入了解重复分析的工作原理。何时可以将代码块称为重复?答案是:当有多个相同代码行被重写用于不同目的时。由于业务端的压力,你可能会觉得如果你为各种任务复制粘贴相同的代码,你的任务将能够按时完成,但 PhpStorm 对此态度表示反对。每当代码重复时,DRY原则就会被违反。每当 DRY 原则被违反时,软件工程要求你确保代码的可重用性。最常见的方法是适当地编写类和方法。由于 PhpStorm 是维护软件工程原则的伟大战士,为了确保这一事业,重复分析会在一个专门的代码重复窗口中列出所有此类发生的情况。

代码格式化和排列

一位 PhpStorm 食谱作者说:“仅仅编写代码并不能让你成为软件工程战士——一个工程师只有在代码运行良好,并且相邻的人能从中理解一些东西时,才能成为忍者。”

人们可能会对这个陈述的有效性提出异议。但鉴于工程师中普遍存在对工作不满的趋势,对于你这样的团队高级软件开发人员来说,控制代码的编写方式变得非常重要。当然,这是你的责任!

如何做…

  1. 当你下定决心确保所写的代码必须格式正确时,你需要从主菜单中选择代码 | 重新格式化代码

  2. 如同往常一样,将弹出一个窗口供你进行选择。非常高兴的是,你可以利用这个弹出窗口做些奇妙的事情,如下面的截图所示:如何做…

  3. 默认选择将格式化当前选定的文件。执行以下步骤以获得所需的结果:

    1. 如果你选择了文本,PhpStorm 只有在提供了所选文本选项的情况下才会格式化所选文本。

    2. 当你在...选项中选择所有文件时,你可以选择特定文件夹中的所有文件。通过选择包含子目录旁边的复选框,你可以选择所选目录内的子目录。

    3. 你可以通过移除代码中不需要的导入来优化导入

    4. 你可以通过选择重新排列条目选项来在目标代码中重新排列导入条目。重新排列条目将重新排列代码中元素出现的顺序。

    5. 你也可以通过选择仅 VCS 更改的文本来仅重新格式化由 Subversion 更改的文本。

    6. 在选择运行按钮后,代码格式化过程开始工作。

它是如何工作的…

格式化系统通过尊重您在代码样式 | PHP中指定的设置来工作。您可以通过选择选项卡来控制制表符和缩进,如下面的截图所示:

如何工作…

代码中要提供的空格是由设置面板中的空格选项卡控制的,如下面的截图所示:

如何工作…

代码中的包裹和括号是由包裹和括号选项卡控制的,如下面的截图所示。此选项卡指定了文本在代码中将如何换行,以及括号在目标代码中将如何格式化。

如何工作…

当在空白行选项卡中进行设置时,代码中会适当地插入空白行,如下面的截图所示:

如何工作…

PHPDoc 也可以进行格式化。还记得这个设置吗?

如何工作…

代码格式化涉及在其他选项卡下可用的各种设置。这提供了不属于其他类别的通用设置。以下截图显示了其他选项卡下找到的代码格式化设置:

如何工作…

类成员的排列是由排列选项卡下的设置驱动的。代码中元素排列的顺序可以在该选项卡下找到。您可以使用管理按钮保存设置,并在其他项目中使用它。如果您已经在那个“其他”项目中,您需要选择蓝色文本从...设置以选择已设置的格式规则,如下面的截图所示:

如何工作…

所有工作都已完成。祝您代码格式化愉快!

在离开厨房之前,我们,作为作者,想声明,由于知识总是在不断演变,因此作为(高级)软件开发者,您不应该将自己限制在有限的知识资源中。作为这一规则的体现,我们计划添加更多因截止日期限制而被跳过的食谱。您可以在 PhpStorm 社区中继续关注更新;同时,作者们将继续致力于 PhpStorm,为您带来更多有趣和美味的佳肴。

这不是结束,而是更多和前所未有类型事物的开始。PhpStorm 很棒!

posted @ 2025-09-07 09:14  绝不原创的飞龙  阅读(40)  评论(0)    收藏  举报