如何在PHP 7之前解决"必须是字符串的实例,字符串给定"?

lee*_*ers 209 php types type-hinting

这是我的代码:

function phpwtf(string $s) {
    echo "$s\n";
}
phpwtf("Type hinting is da bomb");
Run Code Online (Sandbox Code Playgroud)

导致此错误:

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

看到PHP在同一口气中识别并拒绝所需的类型,这不仅仅是一点Orwellian.该死的有五盏灯.

PHP中字符串的类型提示相当于什么?奖励考虑答案,准确解释这里发生了什么.

dec*_*eze 192

在PHP 7之前,类型提示只能用于强制对象和数组的类型.标量类型不是类型可约束的.在这种情况下,类的对象string是预期的,但是你给它一个(标量)string.错误消息可能很有趣,但它不应该开始工作.鉴于动态类型系统,这实际上会产生某种变态感.

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

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

  • 使用数组是让它如此奇怪的原因:p (7认同)
  • 这个答案对PHP 7无效 (3认同)

Yan*_*hon 21

PHP的手册:

类型提示只能是对象和数组(自PHP 5.1以来)类型.不支持使用int和string的传统类型提示.

所以你拥有它.错误信息并不是真的有用,但我给你的是.

**2017年编辑**

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

有效类型

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

警告

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

<?php
   function test(boolean $param) {}
   test(true);
 ?>
Run Code Online (Sandbox Code Playgroud)

上面的例子将输出:

 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
Run Code Online (Sandbox Code Playgroud)

最后一个警告对于理解错误"参数必须是字符串类型,字符串给出"实际上是很重要的; 因为大多数只允许类/接口名称作为参数类型,所以PHP试图找到一个类名"string",但由于它是一个基本类型而无法找到任何类型,因此失败了这个尴尬的错误.


Sur*_*ams 8

PHP允许"提示"提供指定对象的类.根据PHP手册,"类型提示只能是对象和数组(自PHP 5.1以来)类型.不支持使用int和string的传统类型提示." 该错误是令人困惑,因为你选择的"绳子" - 把"MyClass的"在其位和错误将读取不同:"传递给phpwtf(参数1)必须是MyClass的实例,字符串给出"