这是我的代码:

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

这将导致以下错误:

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

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

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


当前回答

在写这个答案的时候,从PHP手册:

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

所以你得到了它。错误信息并不是很有帮助,尽管如此。

** 2017编辑**

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

有效的类型

Class/interface name : The parameter must be an instanceof the given class or interface name. (since PHP 5.0.0) self : The parameter must be an instanceof the same class as the one the method is defined on. This can only be used on class and instance methods. (since PHP 5.0.0) array : The parameter must be an array. (since PHP 5.1.0) callable : The parameter must be a valid callable. (since PHP 5.4.0) bool : The parameter must be a boolean value. (since PHP 7.0.0) float : The parameter must be a floating point number. (since PHP 7.0.0) int : The parameter must be an integer. (since PHP 7.0.0) string : The parameter must be a string. (since PHP 7.0.0) iterable : The parameter must be either an array or an instanceof Traversable. (since PHP 7.1.0)

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

<?php 函数测试(boolean $param) {} 测试(真正的); ? >

上面的例子将输出:

传递给test()的参数1必须是一个boolean实例,boolean给定,在第1行调用,在-:1中定义

最后一个警告实际上对理解错误“Argument must of type string, string given”很重要;由于大多数情况下只有类名/接口名被允许作为参数类型,PHP试图定位类名“string”,但由于它是一个基本类型,所以无法找到任何类型,因此失败并出现这个尴尬的错误。

其他回答

PHP允许在提供类来指定对象时使用“提示”。根据PHP手册,“类型提示只能是对象和数组类型(从PHP 5.1开始)。不支持int和string的传统类型提示。”错误是令人困惑的,因为你选择了“字符串”-把“myClass”放在它的位置,错误将读不同:“传递给phpwtf()的参数1必须是myClass的一个实例,字符串给定”

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

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

在写这个答案的时候,从PHP手册:

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

所以你得到了它。错误信息并不是很有帮助,尽管如此。

** 2017编辑**

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

有效的类型

Class/interface name : The parameter must be an instanceof the given class or interface name. (since PHP 5.0.0) self : The parameter must be an instanceof the same class as the one the method is defined on. This can only be used on class and instance methods. (since PHP 5.0.0) array : The parameter must be an array. (since PHP 5.1.0) callable : The parameter must be a valid callable. (since PHP 5.4.0) bool : The parameter must be a boolean value. (since PHP 7.0.0) float : The parameter must be a floating point number. (since PHP 7.0.0) int : The parameter must be an integer. (since PHP 7.0.0) string : The parameter must be a string. (since PHP 7.0.0) iterable : The parameter must be either an array or an instanceof Traversable. (since PHP 7.1.0)

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

<?php 函数测试(boolean $param) {} 测试(真正的); ? >

上面的例子将输出:

传递给test()的参数1必须是一个boolean实例,boolean给定,在第1行调用,在-:1中定义

最后一个警告实际上对理解错误“Argument must of type string, string given”很重要;由于大多数情况下只有类名/接口名被允许作为参数类型,PHP试图定位类名“string”,但由于它是一个基本类型,所以无法找到任何类型,因此失败并出现这个尴尬的错误。

(最初由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上的类型转换在块内部,php上的字符串不是对象,正如我所知:

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