这是使用错误抑制运算符的不良做法吗?

Posted

技术标签:

【中文标题】这是使用错误抑制运算符的不良做法吗?【英文标题】:Is this bad practice use of the error suppression operator? 【发布时间】:2011-04-06 21:52:59 【问题描述】:

我正在开发一个使用普通数据库方法而不是准备好的语句的数据库驱动站点。因此,当传递给表单操作 php 脚本时,我必须清理 POST 和 GET 变量。

定义了一个 sanitise 方法,该方法试图尽可能地清理用户输入,但我试图减少测试 POST 和 GET 变量是否存在的代码以及使用默认值定义变量的代码,如果它们不存在。

这是我想出的,但它给我和其他开发者留下了不好的印象,因为我们都觉得错误抑制运算符被滥用了:

$Page      = sanitise(@$_GET["page"], "Unspecified");
$Timestamp = sanitise(@$_POST["time"], time());

请你给我一些关于这段代码的评论吗?我同意这并不理想,但它确实减少了很多代码,并且比我们拥有的更具可读性。

我试图在一行中实现以下目标:

    测试变量是否存在。 如果存在,请清理输入并分配给变量。 如果不存在,则创建一个变量但使用默认值。

你怎么看?


这是我在此提出的问题的延续:Passing unset variables to functions

【问题讨论】:

【参考方案1】:

为自己节省一些编码,并使用几个静态函数创建一个“输入”类,如下所示:

class Input 

      public static function get($key, $default = null)
      
            return (array_key_exists($key, $_GET)) ? $_GET[$key] : $default;
      

      // same thing for $_POST...


然后你可以像这样调用你的清理函数......

sanitize(Input::get('page', 'Unspecified'));

【讨论】:

它相当冗长,考虑到它做同样的事情。 @Tomalak - 确实,它需要多几行代码,但它封装了逻辑并使一切更具表现力,IMO。【参考方案2】:

确实,使用@ 运算符通常被认为是不好的做法。

在您的情况下,可以通过将事情分成几个步骤来避免:

设置测试变量 -- 使用isset() 正在处理它 - 或者不: 如果设置,则对其进行消毒 否则,使用默认值。

由于@ 操作符可以避免,这里...好吧,我会避免它。

备注:

掩盖错误通常不是一个好主意(在这种情况下,它应该不会造成太大的伤害......但是,仍然)@ 运营商是有成本的,说到性能1。 单行不是一个人应该有的目标;-)

1. 但有些人会说这并不重要——他们可能是对的

【讨论】:

我同意你所说的,但我试图避免所有额外的步骤。我很喜欢 TaylorOtwell 提出的静态输入类的想法,看看你的想法。【参考方案3】:

您可以使用 terany 运算符来测试是否存在,避免使用错误抑制运算符:

$Page = (!empty($_POST['test'])) ? $_POST['test'] : 'default';

通常使用抑制运算符被视为一种不好的做法,因此像这样使用三元运算符可以避免抑制错误并为您提供所需的效果。

【讨论】:

再次使用所有额外的大括号... $page = !empty($foo) ? $xyz : '默认'; 您缺少一个 ?我无法编辑它,因为该网站很蹩脚,“必须更改超过 6 个字符”【参考方案4】:

@ 运算符并没有避免错误,而是让它变得相当。但是,如果您检查错误,您将得到一个。这就是为什么这是一个不好的做法。但也因为隐藏错误通常会带来麻烦。

一个好办法是这样的:

$Page = (isset($_GET['page'])) ? $_GET['page'] : 'default';
$Page = sanitise($Page, "Unspecified");

但既然你有一个 sanitise() 函数,你可以升级它并为你做这个检查。

function sanitise($value, $default, $fromRequest=false)  
 if ($fromRequest) $value = (isset($_REQUEST[$value])) ? $_REQUEST$value] : $default;
  ..

$_REQUEST 是代表 $_GET + $_POST + $_COOKIE 的全局变量,但你可以自定义我的版本。

【讨论】:

【参考方案5】:

一般来说,其他答案都是正确的。使用@ 只是假装错误不存在存在问题。

也就是说,在这种的情况下,我会使用你的方法。它清晰易读,而且——在这个小场景中——只是完成了工作。我很难想到这里有潜在的错误。

【讨论】:

【参考方案6】:

为了避免带有 isset 的货物崇拜编程语法,我在输入数组周围使用了对象包装器。它专门在幕后进行检查,所以我可以避免愚蠢的isset @.

对于你的例子,我会写$_GET->int->default("time", time())$_GET->sanitize["page"],如果所有规则都是预定义的,则只需$_GET["whatever"] 自动过滤。

否则我仍然会使用@$_GET,因为我不相信外观编码。

【讨论】:

所以你滥用 OO 只是为了避免被视为一只羊。有趣! 如果滥用 OO 是指紧凑的 API 和更少的工作量,是的。

以上是关于这是使用错误抑制运算符的不良做法吗?的主要内容,如果未能解决你的问题,请参考以下文章

@ 抑制运算符的运用

PHP 通知抑制;只有某些情况/方法

Double-splat 运算符破坏性地修改了哈希——这是一个 Ruby 错误吗?

MSVC 无法根据模板参数进行数学运算,这是一个错误吗?

JS 的5个不良编码习惯

这种不良做法/反模式的名称是啥?