PHP TypeError 内部函数的一致类型错误

对于用户定义的函数,传递非法类型的参数会导致 TypeError。 对于内部函数,其行为取决于多种因素,但默认是抛出警告并返回 null。 该 RFC 建议始终为所有无效参数类型生成 TypeError 异常,无论函数是用户定义的还是扩展定义的。

首先,对当前行为的详细描述是有序的。 对于无效类型的用户函数参数,无论 strict_types 选项如何,总是会导致 TypeError:

function foo(int $bar) {}
foo("not an int");
// TypeError: Argument 1 passed to foo() must be of the type int, string given

上述代码错误情况如下所示

PHP TypeError 内部函数的一致类型错误

当然,strict_types 改变了哪些值被认为与某种类型兼容,但它不会修改错误报告机制。 对于内部函数,基本的行为是抛出警告并返回 null:

var_dump(strlen(new stdClass));
// Warning: strlen() expects parameter 1 to be string, object given
// NULL

上述代码产生的错误情况如下所示

PHP TypeError 内部函数的一致类型错误

null 返回值只是大多数函数遵循的约定。 还有大约 150 个函数会返回 false。 但是,如果启用了 strict_types,则会生成 TypeError,这与用户定义的函数一致:

declare(strict_types=1);
var_dump(strlen(new stdClass));
// TypeError: strlen() expects parameter 1 to be string, object given

上面代码产生的错误如下所示

PHP TypeError 内部函数的一致类型错误

此外,有些函数会选择始终生成 TypeError,而不管 strict_types 设置如何。 所有构造函数都是这种情况,因为它们没有返回空值的有意义的方式。 其他函数,例如 random_int 或整个 sodium 扩展,也可以选择抛出。 新引入的方法通常会这样做,以便在所有错误条件下始终抛出异常。

最后,报告错误的方式取决于检测到违规的机制。 以上描述适用于内部函数通常使用的 zend_parse_parameters/ZEND_PARSE_PARAMETERS API。 但是,函数可以另外指定参数信息(通过反射提供)。 如果参数信息指定了类型,那么违反这些将始终导致 TypeError。

这可能导致错误行为取决于哪个参数无效的特殊情况:

var_dump(DateTime::createFromFormat(new stdClass, "foobar"));
// Warning: DateTime::createFromFormat() expects parameter 1 to be string, object given
// bool(false)
 
var_dump(DateTime::createFromFormat("foobar", "foobar", new stdClass));
// TypeError: Argument 3 passed to DateTime::createFromFormat() must be an instance of DateTimeZone or null, instance of stdClass given

在前一种情况下,zend_parse_parameters 检测到类型不匹配并导致警告和错误,在后一种情况下,参数信息检测到类型不匹配并导致 TypeError。 都是为了同一个功能。

免责声明:
1.本站所有内容由本站原创、网络转载、消息撰写、网友投稿等几部分组成。
2.本站原创文字内容若未经特别声明,则遵循协议CC3.0共享协议,转载请务必注明原文链接。
3.本站部分来源于网络转载的文章信息是出于传递更多信息之目的,不意味着赞同其观点。
4.本站所有源码与软件均为原作者提供,仅供学习和研究使用。
5.如您对本网站的相关版权有任何异议,或者认为侵犯了您的合法权益,请及时通知我们处理。
火焰兔 » PHP TypeError 内部函数的一致类型错误