gpt4 book ai didi

PHP 所有函数都应该先检查它们的参数类型吗?

转载 作者:可可西里 更新时间:2023-11-01 12:36:21 26 4
gpt4 key购买 nike

我已经建立了一组字符串函数来做各种事情,我注意到我实际上没有任何内部函数检查来确保变量是一个字符串,然后再对它进行操作。

因此,在开发过程中,有几次我不小心传递了字符串以外的内容,从而导致错误。

现在,我想知道这是否是我应该一直做的事情。首先检查以确保已发送正确类型的数据/首先检查可能出错的事情,以某种方式记录它们,然后如果一切正常,则对其进行处理。

这是我应该坚持的东西吗?

最佳答案

您可以看到这是一个值得商榷的话题。这是我的看法:

类型提示

尽可能使用类型提示。类型提示在 PHP 中对于原始类型是不可能的,所以是的,你应该检查以确保你收到了有效的参数。如果没有,您的函数可以抛出异常或返回一些默认值,如 null 或 false。

防御性编程

编写可测试代码的想法是失败不是无声的或神秘的。没有理由避免显式参数验证:冗长且您的代码更加清晰和可用。

除了验证您的论点之外,您还可以实现错误处理程序来捕获边缘情况。但是您应该验证大多数参数,尤其是当它们对持久数据(例如您的数据库)有影响时。

墨菲定律完全有效,因此您必须尽可能多地应对可预测的错误。无效参数是一个很容易预测的错误——无法验证它是代码中的一颗定时炸弹。例如,调用 is_string 很容易并且可以扩散炸弹。

拳击

另一个考虑因素是“装箱”您的变量。这会导致代码非常冗长,但它确实具有允许为基元提供类型提示的优势。

我从未见过有人通过他们的整个代码库真正做到这一点,但它就在那里。有可用于原始类型的 SPL 类,所以你会像这样结束:

function stringThing (\SplString $myString) { ... }

stringThing(new \SplString('This is my string'));

SplTypes 强制执行原始类型并在滥用时抛出异常。来自文档:

$string = new SplString("Testing");
try {
$string = array(); // <----------this will throw an exception
} catch (UnexpectedValueException $uve) {
echo $uve->getMessage() . PHP_EOL;
}

SplTypes 是一个 PECL 扩展,并不总是标准 PHP 安装的一部分,所以在使用它之前检查你的扩展。该扩展也被认为是实验性的,尽管它已经存在了一段时间。

您还可以非常简单地创建自己的盒子:

class myStringBox {
private $string = '';
public function __construct($string=null) {
if ($string)
$this->set($string);
}
public function set($val) {
if (!is_string($string)) throw new \InvalidArgumentException();
$this->string= $val;
}
public function __toString() {
return $this->string;
}
public function trim() { return trim($this->string); } // extend with functions?
}

...但这有一个主要的功能差异,因为您不能像这样直接设置新的字符串值:

$stringBox = new myStringBox('hello world! ');
echo $stringBox; // "hello world![space]"
echo $stringBox->trim(); // "hello world!"

$stringBox = 'A new string';
echo $stringBox->trim(); // Error: Call to a member function trim() on a non-object

相反,您必须使用 setter 方法:

$stringBox = new myStringBox('hello world! ');
echo $stringBox; // "hello world![space]"
echo $stringBox->trim(); // "hello world!"

$stringBox->set('A new world');
echo $stringBox->trim(); // "A new world"

这一切都让我们回到类型提示,这可能是不必验证您的参数的最有效方法。

相关阅读

关于PHP 所有函数都应该先检查它们的参数类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20098834/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com