【问题标题】:Guarding my methods against bad input保护我的方法免受错误输入
【发布时间】:2013-12-15 11:30:02
【问题描述】:

我有这样的方法:

public function create (array $hash) {
    $id = $hash[ID_KEY];
    $this->store[$id] = $hash;
}

我想保护它免受错误输入引起的错误。 例如,我的代码可能会错误地将$hash 传递给

$id = '' or $id = null,

在这种情况下,它将被null 引用以静默方式存储。相反,我想看到一个警告并修改我的代码以摆脱它。所以我想最好的方法是抛出异常:

if (! $id) throw new Exception("Hash with empty id");

请注意,我使用空字符串作为几个方法参数和默认返回值的默认值,因此很容易出现这种错误。 (这里使用null而不是空字符串似乎并没有改变任何东西,即使鲍勃叔叔不建议这样做。)

问题是——有很多这样的方法。保护 每个 他们中的 each 参数真的是最佳做法,这些参数可以成为 null 但不应该?

例如,另一种方法只进行读取。那么似乎没有必要防范null,因为null 引用的任何内容都不会被存储,对吧?还是我应该继续防守,为将来可能会决定允许null引用的存储而忘记调整警卫的情况做准备?

这听起来是一种最安全的方法,但是会用大量的保护代码来混淆所有方法,其中包含所有涉及的索引。这真的是最好的方法吗?

编辑。 我设置了更多的警卫,确实发现了一些我不会发现的错误。我的测试也没有发现它们。

此外,它有助于更​​好地理解读取方法的作用——如果找到则返回值如果没有则返回empty Array。输入 $id = null 位于 not found 之下,因此也返回 empty Array。这样该方法就干净且一致。

【问题讨论】:

  • 这取决于你想多小心。我认为大多数程序员不会像这样设置很多守卫,他们首先会尝试正确调用他们的函数。
  • @Barmar 我已经尝试过了,但最终痛苦地浪费了太多时间寻找错误。 :(
  • 那就继续吧,在每个函数的开头都加上守卫。
  • @Barmar 它不漂亮,但似乎不那么邪恶。我为此编写了一个通用的 util 函数,所以它只是在每个方法中多写了一行。
  • 特别是因为它被标记为“oop”:正确使用对象可以大大减少此类问题。您将有一些方法必须接受标量类型并检查它们,但如果您要处理大部分正确类型检查的对象,则需要做的验证要少得多。

标签: php oop validation exception null


【解决方案1】:

您可以使用 PHP 的 is_null()empty() 轻松管理这种输出。 另外我建议你写一个只在调试中使用的函数列表(因为你想完善你的代码)。在您要测试的每个方法中调用这些函数,并设置一个类似 DEBUG_MODE 的常量来处理调试函数的行为。所有这些也可以使用unit testing 来完成,这需要更多的注意力和时间。但如果你两者兼有或想学习新的东西,单元测试显然是更好的选择。

此外,处理您能想到的所有案例也是一个好习惯。例如,如果您的“读取方法”不希望找到空值(因为您认为没有空值,因为您通过测试过度测试消除了),如果此“读取方法”碰巧找到空值,则会出现“丑陋”的 PHP 错误会显示在某个地方,或者更糟的是,如果 error_report 关闭,您可能永远看不到问题,或者更糟的是,代码可能会继续执行并彻底损坏更多数据。

【讨论】:

  • 谢谢,这让我更有信心,我不会像痴迷的疯子那样把所有这些警卫放在一起。 :) 我的 read 方法输出空字符串来标记列表的结尾,所以如果做得不好,接收器方法会认为列表已经结束,数据会丢失而没有任何注释。很恶心。所以我想我被守卫困住了。是的,我一直在使用测试,并认为它们基本上取代了 调试模式,但我可能正在重新考虑它......
  • 关于 调试模式 - 我的代码是一个 cron 守护进程,所以我想我应该始终将其保持在 调试模式 以查看错误。
  • 好吧,总是建议使用 switch bool 变量,我认为您只需要偶尔调试一次代码,然后关闭“调试模式”。为此,我会说为每个函数添加一个标头函数有点过分,使用异常会相当快速和有用。尽管您可以将两者结合起来并具有一些帮助您抛出异常的功能(就像我在回答中建议的那样)。还提醒您可以扩展基本的Exceptions 来自定义代码的行为。
猜你喜欢
  • 2017-05-15
  • 2014-12-21
  • 2018-12-26
  • 2010-12-14
  • 2011-07-09
  • 1970-01-01
  • 2014-04-01
  • 2020-03-31
  • 2020-11-17
相关资源
最近更新 更多