这是我的代码:

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

这将导致以下错误:

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

看到PHP同时识别和拒绝所需的类型,这有点像奥威尔。有五盏灯,该死。

PHP中字符串类型提示的等效内容是什么?额外的考虑,答案解释了这里到底发生了什么。


当前回答

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

你只能手动“类型提示”标量类型:

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

其他回答

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

你只能手动“类型提示”标量类型:

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

正如其他人已经说过的,类型提示目前只适用于对象类型。但我认为您触发的特定错误可能是在准备即将到来的字符串类型SplString。

理论上,它的行为像一个字符串,但由于它是一个对象,将通过对象类型验证。不幸的是,PHP 5.3中还没有,可能会在5.4中出现,所以还没有测试。

(最初由leepowers在他的问题中发布)

错误消息之所以令人困惑,有一个重要原因:

基本类型名在PHP中不保留

以下是所有有效的类声明:

class string { }
class int { }
class float { }
class double { }

我的错误在于认为错误消息仅仅是指字符串基本类型——“实例”这个词应该让我停顿一下。举个例子进一步说明:

class string { }
$n = 1234;
$s1 = (string)$n;
$s2 = new string();
$a = array('no', 'yes');
printf("\$s1 - primitive string? %s - string instance? %s\n",
        $a[is_string($s1)], $a[is_a($s1, 'string')]);
printf("\$s2 - primitive string? %s - string instance? %s\n",
        $a[is_string($s2)], $a[is_a($s2, 'string')]);

输出:

$s1 -原始字符串?是字符串实例?没有 $s2 -原始字符串?无字符串实例?是的

在PHP中,字符串可以是字符串,除非它实际上是字符串。与任何使用隐式类型转换的语言一样,上下文就是一切。

由于PHP 7.0的类型声明允许标量类型,所以现在可以使用这些类型:self, array, callable, bool, float, int, string。前三个是在PHP 5中提供的,但后四个是在PHP 7中新增的。如果你使用任何其他的(例如整数或布尔),将被解释为类名。

有关更多信息,请参阅PHP手册。

当从Laravel控制器调用函数到PHP文件时,我得到了这个错误。

几个小时后,我发现了问题:我在一个静态函数中使用了$this。