在生产代码中放置条件"debug mode"(if\else)块是否不好的做法 - PHP



我正在为一个处理数据并确保它符合我的确切规范的个人项目编写一些类。 输出是一个数组(API 的 JSON 对象),由相应字段的 true\false 值组成,以查看它们是否通过了我的测试。

一些测试很复杂,具有多种条件,很难从表面上确定字段未通过测试的原因。

对于每个测试,我都在考虑放置一个可以在对象实例化时启用的 DEBUG 标志。 这给我留下了两个选择。

A) 按如下方式复制验证函数。 在 debug_validate() 函数中,我返回一个附加数组,其中包含字段及其失败的原因。 这需要我维护函数的两个副本。

if ($this->debug_mode) {
debug_validate();
}else{
validate();
}

B)在实际的验证函数中,我可以执行以下操作

if (!test1($field)) {
$validation_result[$field]=false;
if($this->debug_mode) {
$debug_result[$field]="Field is too small. Result of strlen: ".strlen($field);
}
}
.
.
.

这意味着每次验证函数运行时我都必须运行"if"块,即使它在 99.99999999% 的时间内不会被使用。 这似乎效率低下。

我是不是想多了。 我的意思是现代硬件,谁关心它是否运行额外的 if 语句。 我只是想知道在生产中,当涉及到数百万个请求时,这是否真的重要(必须考虑大:)),并且这些调试语句开始加起来(这里很少 MS,那里很少 MS)

好吧,如果你是为一家公司写这篇文章,那么是的,这将是一个不好的做法。团队会在代码审查期间将代码反馈给您,并让您删除调试代码。

由于您正在开发个人项目,因此现在可以使用调试代码。好处是它将帮助您更快地调试项目,而不是没有它。您可以稍后在为最终生产版本烘焙代码时清理代码。或者,如果您要在未来版本中从beta状态切换到gold状态(例如 6 个月或 1 年后)。

困难的部分是查看服务器发生了什么,在那里您无法直接访问源代码。这通常是在 QA、测试、暂存或生产服务器上发生的情况。您可以在 localhost 框中轻松编辑代码,但无法在其他服务器上轻松编辑它。

您不想做的是将其保持打开状态,而不编写安全保护它的方法。您不希望其他人能够触发此代码...if ($this->debug_mode) {.如果你在那个PHP块里放了一些重要的东西......像SQL...然后有人可以看到它并开始了解你的数据库是如何布局的。它会给他们一个线索,让他们知道该去哪里,开始入侵你的数据库。他们将希望开始提升其用户访问权限!您不希望他们使自己成为管理员并将您锁定在自己的数据库之外!因此,请确保使用如下内容保护代码:

if (($_SERVER['HTTP_HOST'] === 'qa.yoursite.com') && ($this->debug_mode)) {
debug_validate(); // <- QA uses this.
} else {
validate(); // <- Production uses this.
}

注意:它只在 QA 服务器上运行,但它适用于所有可以使用该服务器的人!因此,请注意,除了您自己之外,不要将QA服务器的访问权限授予任何其他人!

如果您具有带有 userId 的密码保护登录,则可以使用此示例。它将在任何服务器上工作。您还可以组合这两个代码示例,将 userId 锁定到特定服务器。

if ($myUserId === 'myUserId') {
debug_validate(); // <- You'll use this.
} else {
validate(); // <- Everyone else uses this.
}

理想情况下,您要做的是只使用validate();代码而不使用debug_validate();代码,并设置单元测试以针对您的代码运行。它应该包括测试,以验证所有内容是否正确验证。它还应包括测试,以验证错误数据不会验证。当您的网站达到该级别时,您将不再需要使用debug_validate()方法。单元测试将报告一切是否良好或失败。

此时我不会担心ms加载时间。也不是服务器负载。PHP 代码运行得如此之快,以至于您不会注意到它。更专注于让代码正常工作,而不是让它看起来很漂亮。您始终可以在以后重构代码,以便在代码正常工作后对其进行清理。当您看到工作代码变得干净时,它会让您感到更快乐!

在任何一种情况下,您的生产代码都必须计算一个额外的"IF"条件,除非我误解了?无论是在函数中还是在调用脚本中,无论哪种方式,额外的开销(即使在负载下也可能非常小,除非你有数千个)都是相同的。

我过去有过带有"调试模式"类型标志的生产代码,它工作得很好 - 但是,这种方法存在一些问题 - 即您需要更改代码(即打开或关闭标志),因此执行另一个构建/部署以进行调试。此外,记住打开/关闭调试模式可能是一件苦差事。它往往会弄脏你的代码/使其可读性降低/易于维护。

就个人而言,我会采取一些不同的方法,特别是如果您认为调试对您的应用程序来说很常见 - 您可以使用 PHP Unit 等工具编写单独的单元测试来进行调试。如果要以某种形状或形式记录对应用程序的传入请求,则应该可以轻松地将生产数据传送到单元测试代码库,并在该环境中而不是在生产代码中执行调试。

如果您运行的是测试驱动开发环境,那么无论如何,首先编写单元测试应该是常见的做法。

最新更新