我想知道你认为在PHP中检查参数的最佳实践是什么?也就是说,在实施参数类型检查与不进行参数类型检查的项目中,你是否真正看到了明显较少的错误?我正在考虑像这样的事情:
public function __construct($screenName, $createdAt) {
if (!is_string($screenName) || !is_string($createdAt) {
return FALSE;
}
}
我想知道你认为在PHP中检查参数的最佳实践是什么?也就是说,在实施参数类型检查与不进行参数类型检查的项目中,你是否真正看到了明显较少的错误?我正在考虑像这样的事情:
public function __construct($screenName, $createdAt) {
if (!is_string($screenName) || !is_string($createdAt) {
return FALSE;
}
}
通常情况下,在使用PHP应用程序中,使用标量变量“types”实际上是绑定到字符串输入(HTTP请求)的。PHP使将字符串输入转换为数字更加容易,这样您就可以将其用于计算等操作。
然而,像您提供的示例中建议的那样检查标量值是否为is_string
并没有太多意义。因为标量家族中的几乎任何类型的变量都是字符串,或者至少可以用作字符串。因此,对于您的类示例,问题是,检查变量类型是否实际上有意义呢?
对于您提出的代码来说,它没有任何意义,因为您在构造函数中使用return false;
退出。这将结束构造函数的运行并返回一个未经适当初始化的对象。
相反,如果构造函数的参数未提供所需的值类型,则应抛出异常,例如InvalidArgumentException
。
不考虑这一点,并且默认构造函数需要区分字符串、整数、布尔或任何其他标量类型,那么您应该进行检查。
如果您不依赖于精确的标量类型,则可以将其转换为字符串。
只要确保对象内部隐藏的数据始终完全正确,并且不可能将错误的数据插入到私有成员中即可。
'12345'
,那么很难区分它和数字12345
之间的区别。__toString
,PHP将报错。因此,您唯一真正的问题是具有__toString
方法的类,这种情况可能非常少见。我真的想知道它是否值得这样的开销。检查函数参数是一种非常好的实践。我怀疑人们通常不这样做是因为他们的函数变得越来越大,代码变得更加丑陋和难以阅读。现在,在PHP 7中,您可以对标量类型进行类型提示,但仍然没有解决方案,用于当您希望参数是两种类型之一时:数组或\ Traversable实例(两者都可以使用foreach遍历)。
在这种情况下,我建议看一下args模块,它来自NSPL。您示例中的__constructor将如下所示:
public function __construct($screenName, $createdAt)
{
expectsAll(string, [$screenName, $createdAt]);
}
// or require a non-empty array, string or instance of \ArrayAccess
function first($sequence)
{
expects([nonEmpty, arrayAccess, string], $sequence);
return $sequence[0];
}
更多示例 在这里。
当你是唯一与方法交互的人时,更好的文档非常重要。标准的方法定义注释可以为您提供良好的文档化方法,这些方法可以轻松编译成 API,然后在许多 IDE 中使用。
然而,当您将您的库或输入暴露给其他人时,进行类型检查并在代码无法与其输入配合使用时抛出错误是很好的。对用户输入进行类型检查可以保护您免受错误和黑客攻击,并且作为一个库,让其他开发人员知道他们提供的输入不是您所期望的有时是很好的。
$createdAt
也可以是时间戳(int
)或对象(DateTime
)。 - KingCrunch$createdAt
的参数,我最后会假设它是string
类型,但在这里不被接受(实际上在这里是被接受的,因为构造函数中的return false;
没有任何效果,如果类型不匹配,什么也不会发生,但这只是因为示例有点不完整)。我的意思是,在这种情况下严格的类型限制可能会导致更多的混淆,而不是帮助某人。 - KingCrunch