为什么 PHP 严格类型允许错误类型的函数参数?
Why does PHP strict typing allow function arguments of wrong type?
我正在使用 PHP 7.4.16。我在我的 PHP 文件中启用了 strict_types
,认为它会通过抛出 TypeError
来阻止将 string
参数传递给期望 int
的函数。但是,该函数实际上接受 string
并将其强制转换为 int
。但是,如果我在函数上放置一个 return 类型提示,它会按预期工作,抛出一个 TypeError
.
这对我来说没有意义,而且看起来很明显的不一致会导致错误。有没有人知道这是为什么,或者我做错了什么?
测试代码:
<?php
declare(strict_types=1);
$ids = ['1', '2', '3'];
// No error thrown, coerces string argument to int.
array_map(fn (int $id) => $id, $ids);
// Throws PHP Fatal error: Uncaught TypeError: Return value of {closure}() must be of the type int, string returned
array_map(fn ($id): int => $id, $ids);
strict_types
只影响声明它的文件中的函数调用。来自 PHP 文档:
Note:
Strict typing applies to function calls made from within the file with strict typing enabled, not to the functions declared within that file. If a file without strict typing enabled makes a call to a function that was defined in a file with strict typing, the caller's preference (coercive typing) will be respected, and the value will be coerced.
在您的例子中,这些示例没有调用回调本身,而是将其作为 array_map
的参数传递,这意味着无论在何处实现函数 array_map
,它都优先考虑强制在 array_map
调用您的回调时输入。
一个可能的解决方案是包装 array_map
并在声明 strict_types 的文件中调用您的回调,例如:
<?php
declare(strict_types=1);
$ids = ['1', '2', '3'];
function strict_array_map($fn, $arr){
return array_map(fn (...$arguments) => $fn(...$arguments), $arr);
}
// Now TypeError is thrown correctly
strict_array_map(fn (int $id) => $id, $ids);
// Throws PHP Fatal error: Uncaught TypeError: Return value of {closure}() must be of the type int, string returned
strict_array_map(fn ($id): int => $id, $ids);
https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations.strict
我正在使用 PHP 7.4.16。我在我的 PHP 文件中启用了 strict_types
,认为它会通过抛出 TypeError
来阻止将 string
参数传递给期望 int
的函数。但是,该函数实际上接受 string
并将其强制转换为 int
。但是,如果我在函数上放置一个 return 类型提示,它会按预期工作,抛出一个 TypeError
.
这对我来说没有意义,而且看起来很明显的不一致会导致错误。有没有人知道这是为什么,或者我做错了什么?
测试代码:
<?php
declare(strict_types=1);
$ids = ['1', '2', '3'];
// No error thrown, coerces string argument to int.
array_map(fn (int $id) => $id, $ids);
// Throws PHP Fatal error: Uncaught TypeError: Return value of {closure}() must be of the type int, string returned
array_map(fn ($id): int => $id, $ids);
strict_types
只影响声明它的文件中的函数调用。来自 PHP 文档:
Note: Strict typing applies to function calls made from within the file with strict typing enabled, not to the functions declared within that file. If a file without strict typing enabled makes a call to a function that was defined in a file with strict typing, the caller's preference (coercive typing) will be respected, and the value will be coerced.
在您的例子中,这些示例没有调用回调本身,而是将其作为 array_map
的参数传递,这意味着无论在何处实现函数 array_map
,它都优先考虑强制在 array_map
调用您的回调时输入。
一个可能的解决方案是包装 array_map
并在声明 strict_types 的文件中调用您的回调,例如:
<?php
declare(strict_types=1);
$ids = ['1', '2', '3'];
function strict_array_map($fn, $arr){
return array_map(fn (...$arguments) => $fn(...$arguments), $arr);
}
// Now TypeError is thrown correctly
strict_array_map(fn (int $id) => $id, $ids);
// Throws PHP Fatal error: Uncaught TypeError: Return value of {closure}() must be of the type int, string returned
strict_array_map(fn ($id): int => $id, $ids);
https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations.strict