如何解决 PHP 7 之前的“必须是字符串的实例,给出字符串”?

2022-08-30 06:17:38

这是我的代码:

function phpwtf(string $s) {
    echo "$s\n";
}
phpwtf("Type hinting is da bomb");

这会导致此错误:

可捕获的致命错误:传递给 phpwtf() 的参数 1 必须是字符串的实例,给定字符串

看到PHP同时识别和拒绝所需的类型,这不仅仅是一个奥威尔式的。有五盏灯,该死的。

PHP 中字符串的类型提示的等效项是什么?对答案的奖励考虑,可以准确解释这里发生了什么。


答案 1

在 PHP 7 之前,类型提示只能用于强制对象和数组的类型。标量类型不可类型提示。在这种情况下,类的对象是预期的,但你给它一个(标量)。错误消息可能很有趣,但它不应该一开始就起作用。考虑到动态类型系统,这实际上具有某种的意义。stringstring

您只能手动“键入提示”标量类型:

function foo($string) {
    if (!is_string($string)) {
        trigger_error('No, you fool!');
        return;
    }
    ...
}

答案 2

来自 PHP 的手册

类型提示只能是对象和数组(从 PHP 5.1 开始)类型。不支持使用 int 和字符串的传统类型提示。

所以你有它。错误消息并没有真正的帮助,我给你。

** 2017 编辑 **

PHP7引入了更多的函数数据类型声明,前面提到的链接已经移动到函数参数:类型声明。从该页面:

有效类型

  • 类/接口名称 :参数必须是给定类或接口名称的实例。(自 PHP 5.0.0 起)
  • self :参数必须是与定义方法的类相同的类的实例。这只能用于类和实例方法。(自 PHP 5.0.0 起)
  • 数组 :参数必须是数组。(自 PHP 5.1.0 起)
  • 可调用:参数必须是有效的可调用参数。(自 PHP 5.4.0 起)
  • bool :参数必须是布尔值。(自 PHP 7.0.0 起)
  • float :参数必须是浮点数。(自 PHP 7.0.0 起)
  • int :参数必须是整数。(自 PHP 7.0.0 起)
  • 字符串 :参数必须是字符串。(自 PHP 7.0.0 起)
  • 可迭代:参数必须是可遍历的数组或实例。(自 PHP 7.1.0 起)

警告

不支持上述标量类型的别名。相反,它们被视为类名或接口名。例如,使用布尔值作为参数或返回类型将需要一个参数或返回值,该参数或返回值是类或接口布尔值的实例,而不是 bool 类型:

<?php
  function test(boolean $param) {}
  test(true);
?>

上面的示例将输出:

 Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of boolean, boolean given, called in - on line 1 and defined in -:1

最后一个警告实际上对于理解错误“参数必须为字符串类型,给定字符串”具有重要意义;由于大多数情况下只允许类/接口名称作为参数类型,PHP尝试查找类名“string”,但由于它是基元类型而找不到,因此失败并出现此尴尬的错误。


推荐