”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 掌握 PHP:类型提示技术

掌握 PHP:类型提示技术

发布于2024-11-08
浏览:390

Mastering PHP: Type Hinting techniques
照片由??? ???关于 Unsplash

类型提示被一些人认为是功能的圣杯。所有编程语言都必须具备的一种。 PHP 很长一段时间都没有这样的系统,但现在已被大多数开发人员广泛采用。

也就是说,PHP 的类型系统不如其他语言。许多实现了所谓的泛型。这是在结构和集合之间强制执行类型的能力。例如,在 Java 中,我们可以指定数组必须仅包含某种类型的项目,例如字符串数组。

也许有一天我们也会在 PHP 中拥有这个功能,但在那之前我们实际上可以通过一些不同的技术来解决这个问题。由于缺乏更好的描述,我将它们称为软类型提示运行时提示

类型提示

第一个也是最明显的类型提示是 PHP 7 中引入的类型提示,并且仍在添加到 PHP 中。类型提示常量仅在 PHP 8.3 中添加。

类型提示有助于传达需要作为参数传递给方法或函数的内容或该方法将返回的内容。类型提示将影响它们使用的任何类的签名,因为扩展具有已建立的类型提示的类将意味着它们不能被覆盖。

充分利用类型的类的示例是:




当然,我们的类型提示存在限制,因为如前所述,我们不能使数组全部具有相同的类型,而必须只使用 array 。我们也不能将数字限制为只能是正数或在某个范围内。

另一种可能是闭包,因为无法在 PHP 的本机类型中描述匿名函数。相反,我们必须使用 \Closure 或 callable 。通常,callable 也不允许用作类型。

幸运的是,仍然有一种方法可以使用类型提示来描述这些更复杂的场景。

软类型提示

我们的下一种类型提示是通过 PHPDocs 提供的。如果传递方法或返回错误类型,本机类型将在运行时引发异常,但 PHPDoc 类型提示对应用程序的运行时没有影响。

相反,软类型提示纯粹是在我们使用 VS Code 或 PHPStorm 等 IDE 时为我们提供帮助,它们会为我们检测这些类型。另一个用例是使用 PHPStan 和随后的 Rector 等静态分析工具。

使用软类型的最大优点是它可以让你更精确地描述任何参数、属性等的类型。例如,我们可以采用前面的类,更容易理解所使用的数组或闭包.




确保所有类型使用正确的最佳方法是安装 PHPStan。从那里您可能需要至少使用级别 5。然后可以通过持续集成步骤来检查类型提示是否正确。

如果您想使用正确的软类型提示,实际上可以使用一个列表。更好的是,如果您不确定并想要运行快速测试,可以使用 PHPStan 工具来测试 PHPStan 暗示的所有类型是否正确。

运行时提示

我们支持类型的下一个方法是使用运行时提示。这实际上意味着执行我们自己的代码来检查参数的类型。例如,我们可以检查数组是否只包含特定类型的对象。如果没有,那么我们抛出一个 InvalidArgumentException。




顺便说一下,这种技术有时被称为防御性编程。看看代码示例,这相当麻烦。只是为了简单地检查数组是否正确而编写了很多代码。这就是为什么我们经常求助于库,在本例中是 webmozart/assert .


composer require webmozart/assert


现在安装了这个软件包,我们可以将其缩短为简单的一行。




这个库的一大优点是,如果您向 PHPStan 添加 Assert 扩展,这将有助于分析代码时的类型覆盖率。

结论

总之,掌握 PHP 中的类型提示对于希望编写干净、可维护且可靠的代码的开发人员来说是一项基本技能。虽然 PHP 的类型系统仍然缺乏其他语言中的一些功能,例如泛型,但有多种策略可用于强制执行更严格的类型  —  无论是通过本机类型提示、PHPDoc 注释还是运行时检查。利用 PHPStan 等工具和 Assert 等库可以帮助您确保类型安全,即使在复杂的场景中也是如此。通过将这些技术集成到您的开发工作流程中,您将能够更好地自信而精确地处理 PHP 的动态特性。

我是 Peter Fox,一位在英国使用 Laravel 的软件开发人员。感谢您阅读我的文章,我还有更多内容可以阅读 https://articles.peterfox.me。我现在也是 GitHub 上的赞助者。如果您想鼓励我写更多这样的文章,请考虑捐赠一笔小额一次性捐款。

版本声明 本文转载于:https://dev.to/peter_fox/mastering-php-type-hinting-techniques-3g8e?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何使用Regex在PHP中有效地提取括号内的文本
    如何使用Regex在PHP中有效地提取括号内的文本
    php:在括号内提取文本在处理括号内的文本时,找到最有效的解决方案是必不可少的。一种方法是利用PHP的字符串操作函数,如下所示: 作为替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式来搜索特...
    编程 发布于2025-03-11
  • 如何使用FormData()处理多个文件上传?
    如何使用FormData()处理多个文件上传?
    )处理多个文件输入时,通常需要处理多个文件上传时,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    编程 发布于2025-03-11
  • 大批
    大批
    [2 数组是对象,因此它们在JS中也具有方法。 切片(开始):在新数组中提取部分数组,而无需突变原始数组。 令ARR = ['a','b','c','d','e']; // USECASE:提取直到索引作...
    编程 发布于2025-03-11
  • 如何使用PHP从XML文件中有效地检索属性值?
    如何使用PHP从XML文件中有效地检索属性值?
    从php $xml = simplexml_load_file($file); foreach ($xml->Var[0]->attributes() as $attributeName => $attributeValue) { echo $attributeName,...
    编程 发布于2025-03-11
  • 如何在Java字符串中有效替换多个子字符串?
    如何在Java字符串中有效替换多个子字符串?
    在java 中有效地替换多个substring,需要在需要替换一个字符串中的多个substring的情况下,很容易求助于重复应用字符串的刺激力量。 However, this can be inefficient for large strings or when working with nu...
    编程 发布于2025-03-11
  • 可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    [2这里: https://webthemez.com/demo/sticky-multi-header-scroll/index.html </main> <section> { display:grid; grid-template-...
    编程 发布于2025-03-11
  • 如何使用替换指令在GO MOD中解析模块路径差异?
    如何使用替换指令在GO MOD中解析模块路径差异?
    在使用GO MOD时,在GO MOD 中克服模块路径差异时,可能会遇到冲突,其中3个Party Package将另一个PAXPANCE带有导入式套件之间的另一个软件包,并在导入式套件之间导入另一个软件包。如回声消息所证明的那样: go.etcd.io/bbolt [&&&&&&&&&&&&&&&&...
    编程 发布于2025-03-11
  • 对象拟合:IE和Edge中的封面失败,如何修复?
    对象拟合:IE和Edge中的封面失败,如何修复?
    To resolve this issue, we employ a clever CSS solution that solves the problem:position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%)...
    编程 发布于2025-03-11
  • 为什么尽管有效代码,为什么在PHP中捕获输入?
    为什么尽管有效代码,为什么在PHP中捕获输入?
    在php ;?>" method="post">The intention is to capture the input from the text box and display it when the submit button is clicked.但是,输出...
    编程 发布于2025-03-11
  • 如何使用组在MySQL中旋转数据?
    如何使用组在MySQL中旋转数据?
    在关系数据库中使用mySQL组使用mySQL组进行查询结果,在关系数据库中使用MySQL组,转移数据的数据是指重新排列的行和列的重排以增强数据可视化。在这里,我们面对一个共同的挑战:使用组的组将数据从基于行的基于列的转换为基于列。 Let's consider the following ...
    编程 发布于2025-03-11
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    删除匿名事件侦听器将匿名事件侦听器添加到元素中会提供灵活性和简单性,但是当要删除它们时,可以构成挑战,而无需替换元素本身就可以替换一个问题。 element? element.addeventlistener(event,function(){/在这里工作/},false); 要解决此问题,请考虑...
    编程 发布于2025-03-11
  • 如何使用PHP将斑点(图像)正确插入MySQL?
    如何使用PHP将斑点(图像)正确插入MySQL?
    essue VALUES('$this->image_id','file_get_contents($tmp_image)')";This code builds a string in PHP, but the function call ...
    编程 发布于2025-03-11
  • 如何在JavaScript对象中动态设置键?
    如何在JavaScript对象中动态设置键?
    在尝试为JavaScript对象创建动态键时,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正确的方法采用方括号: jsobj ['key''i] ='example'1; 在JavaScript中,数组是一...
    编程 发布于2025-03-11
  • 为什么我会收到MySQL错误#1089:错误的前缀密钥?
    为什么我会收到MySQL错误#1089:错误的前缀密钥?
    mySQL错误#1089:错误的前缀键错误descript [#1089-不正确的前缀键在尝试在表中创建一个prefix键时会出现。前缀键旨在索引字符串列的特定前缀长度长度,可以更快地搜索这些前缀。了解prefix keys `这将在整个Movie_ID列上创建标准主键。主密钥对于唯一识别...
    编程 发布于2025-03-11
  • 为什么不使用CSS`content'属性显示图像?
    为什么不使用CSS`content'属性显示图像?
    在Firefox extemers属性为某些图像很大,&& && && &&华倍华倍[华氏华倍华氏度]很少见,却是某些浏览属性很少,尤其是特定于Firefox的某些浏览器未能在使用内容属性引用时未能显示图像的情况。这可以在提供的CSS类中看到:。googlepic { 内容:url(&#...
    编程 发布于2025-03-11

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3