PHP中防御性编程的更多提示
构建稳健的PHP应用:防御式编程策略
本文探讨防御式编程在PHP开发中的重要性,并提供一些关键策略以提升应用的健壮性和效率。防御式编程并非为了避免测试驱动开发,而是为了在问题发生前预见并规避潜在的故障点。
核心要点:
- 防御式编程旨在预测潜在的故障点,并在其发生前采取措施进行规避。
- “快速失败,大声报错”是一种有效的防御式编程方法。错误应尽早出现并发出警报,尤其是在处理用户输入或来自外部系统(例如API)的输入时。
- 输入验证、防止比较中的意外赋值、try/catch异常处理和数据库事务是防御式编程的关键方面。
防御式编程的定义:
防御式编程,简单来说,就是以预测潜在故障点为目的进行编程。目标是在这些问题发生之前规避它们。
许多人反对防御式编程,但这往往是因为他们所见到的某些防御式编程方法。防御式编程不应被视为避免测试驱动开发或仅仅是弥补故障的一种方式。
“快速失败”不应被视为防御式编程的对立面。两者都属于同一范畴。这些方法如果不是为了预测程序可能失败,并预防或妥善处理这些失败,那又是什么呢?
快速失败,大声报错
简单来说,“快速失败,大声报错”意味着当发生错误时,它会尽早发生,并向相关人员发出警报,而不是在错误状态下默默继续运行,这可能会导致更多问题。
这种方法在处理用户输入或来自脚本、模块或系统外部(例如通过API)的输入时最为有用。一个应用场景是检查传递给函数的无效值或数据类型。
function thisTestFunction($testInt) { if (!is_int($testInt)) { // 执行某些操作 } }
一些程序员在使用“快速失败”方法时的一个错误是,只是简单地向用户抛出异常和错误,而没有为处理它们做好适当的准备。您不希望普通用户因您的错误消息而感到担忧或困惑。更重要的是,您不希望恶意用户从显示给他们的信息中学习到任何东西。向用户显示有帮助的消息,记录您的错误,并执行任何其他需要作为该异常结果的任务。您不希望只是快速失败,您还需要大声(立即知道存在问题)和安全(不要让您糟糕的异常处理或完全缺乏异常处理导致更多安全问题)。
输入验证
有很多方法可以安全地验证用户输入。
类型转换是一种有趣的“验证”用户输入的方法。有时它看起来像这样:
function thisTestFunction($testInt) { if (!is_int($testInt)) { // 执行某些操作 } }
它没有使用其他方法来避免跨站点脚本攻击,而是简单地捕获、类型转换并赋值。这仅在您有预期类型并且该类型的任何值都是安全的情况下才有效(否则,您还需要检查适当的整数值)。我认为这种方法的问题(在大多数情况下)是您并没有真正检查输入,而只是强制它成为它应该成为的样子。这可能会产生意想不到的后果。相反,更好的方法可能是使用filter_input()
来检查适当的值。
$member->property = (int)$_GET['property'];
在现代PHP中使用原生filter_input
函数有很多好处,您可以在上述文章或php.net上了解更多信息。
防止比较中的意外赋值
这是一个简单且经常被注意到的防御式编程原则。在比较方式上进行简单的更改可以产生巨大的影响。考虑以下情况:
$member->property = filter_input(INPUT_GET, 'property', FILTER_VALIDATE_INT); if (false === $member->property) { throw new Exception('Property was not an int'); }
这是一个相对正常的比较,对吧?但是,如果您不小心使用“=”而不是“==”(或者在大多数情况下,更好的“===”)会发生什么?键盘上手指的简单滑动?健忘,也许?突然之间,您的比较总是、在所有情况下都为真。除非您的IDE警告您这一点,否则您需要多长时间才能发现它?在某些情况下,这可能是一段时间内的静默错误。但是,有一种极其简单的方法可以防止这种情况:
if ($member->property == 12345) { // 执行很酷的操作 } else { // 不执行任何有趣的操作 }
现在,如果您不小心使用一个等号,错误就不会是静默的。显然,这种情况可能不会经常发生,它可能被您的测试所减轻,并且在所有情况下都不实用,尤其是在进行变量到变量的比较时。但如果您倾向于发生这种情况,这仍然不是一个坏主意。
处理Try/Catch和异常
try/catch语句是PHP开发人员中的另一个热门话题。让我们首先快速了解一下我们正在讨论的内容。
if (12345 == $member->property) { // 执行很酷的操作 } else { // 不执行任何有趣的操作 }
防御式编程的一个知名工具是try/catch语句和Exception类。当正确使用时,它们非常适合捕获和记录错误。一个优秀的程序员会使用try/catch语句来预测可能导致中断正常流程的错误或其他情况。当这些异常发生时,必须以适当的方式处理它们。如果需要,应用程序的用户应该收到尽可能有用的合理错误消息,而不会泄露敏感信息。应用程序的管理员应该收到详细的警报和/或日志。未经处理或被忽略的异常会忽略“大声报错”的建议,并可能允许程序在本质上处于静默错误状态一段时间,这对任何相关人员都不利。
事务
事务是数据库的一项功能,它允许将查询组合在一起,以便如果一个查询失败,所有查询都失败。这是ACID的实现,您可以在此处阅读更多相关信息。其思想是,将多个查询组合成一个过程有时可能是一种更安全、更稳定的解决方案,尤其是在查询相互依赖的情况下。PHP开发人员经常完全忽略事务,或假设它们是不必要的,但在与数据库交互时,一些防御式编程可以大有帮助。事务在本文中进行了更深入的讨论,但简而言之,事务允许您运行MySQL更新,然后在实际提交结果之前检查结果。如果您使用的是PDO(您应该使用),您可以使用PDO方法开始事务、提交结果以及回滚。除了上述关于事务的概述之外,还可以通过本深入指南进一步研究它们。
结论
这些只是一些通用的技巧。显然,它们每个都有其用途,并且每个都有其不适用的显著情况。但是,如果您将这些概念融入到您的日常开发制度中,它可以提高您工作的效率。虽然这通常是一个更适用于目前正在学习PHP的开发人员的话题,但对于每个人来说,它都是对实践的良好回顾。
如果只有一件事被记住,特别是对于较新的开发人员,那就是您应该进行防御式编程——计划可能出现的错误。妥善处理它们。不要让静默错误继续发展。快速失败。测试您的代码。通过构建测试并解决问题,并预测和处理未来问题的健壮应用程序,您可以使您的应用程序更可靠,并有望在幕后帮助创造更好的用户体验。
以上是PHP中防御性编程的更多提示的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

会话劫持可以通过以下步骤实现:1.获取会话ID,2.使用会话ID,3.保持会话活跃。在PHP中防范会话劫持的方法包括:1.使用session_regenerate_id()函数重新生成会话ID,2.通过数据库存储会话数据,3.确保所有会话数据通过HTTPS传输。

SOLID原则在PHP开发中的应用包括:1.单一职责原则(SRP):每个类只负责一个功能。2.开闭原则(OCP):通过扩展而非修改实现变化。3.里氏替换原则(LSP):子类可替换基类而不影响程序正确性。4.接口隔离原则(ISP):使用细粒度接口避免依赖不使用的方法。5.依赖倒置原则(DIP):高低层次模块都依赖于抽象,通过依赖注入实现。

在PHPStorm中如何进行CLI模式的调试?在使用PHPStorm进行开发时,有时我们需要在命令行界面(CLI)模式下调试PHP�...

如何在系统重启后自动设置unixsocket的权限每次系统重启后,我们都需要执行以下命令来修改unixsocket的权限:sudo...

静态绑定(static::)在PHP中实现晚期静态绑定(LSB),允许在静态上下文中引用调用类而非定义类。1)解析过程在运行时进行,2)在继承关系中向上查找调用类,3)可能带来性能开销。
