这是我的代码:
function phpwtf(string $s) {
echo "$s\n";
}
phpwtf("Type hinting is da bomb");
这将导致以下错误:
可捕捉的致命错误:传递给phpwtf()的参数1必须是string的实例,string给定
看到PHP同时识别和拒绝所需的类型,这有点像奥威尔。有五盏灯,该死。
PHP中字符串类型提示的等效内容是什么?额外的考虑,答案解释了这里到底发生了什么。
这是我的代码:
function phpwtf(string $s) {
echo "$s\n";
}
phpwtf("Type hinting is da bomb");
这将导致以下错误:
可捕捉的致命错误:传递给phpwtf()的参数1必须是string的实例,string给定
看到PHP同时识别和拒绝所需的类型,这有点像奥威尔。有五盏灯,该死。
PHP中字符串类型提示的等效内容是什么?额外的考虑,答案解释了这里到底发生了什么。
我认为php上的类型转换在块内部,php上的字符串不是对象,正如我所知:
<?php
function phpwtf($s) {
$s = (string) $s;
echo "$s\n";
}
phpwtf("Type hinting is da bomb");
在写这个答案的时候,从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 7之前,类型提示只能用于强制对象和数组的类型。标量类型不是类型暗示的。在这种情况下,期望类字符串的对象,但您给了它一个(标量)字符串。错误消息可能很有趣,但它一开始就不应该工作。考虑到动态类型系统,这实际上有某种扭曲的意义。
你只能手动“类型提示”标量类型:
function foo($string) {
if (!is_string($string)) {
trigger_error('No, you fool!');
return;
}
...
}
PHP允许在提供类来指定对象时使用“提示”。根据PHP手册,“类型提示只能是对象和数组类型(从PHP 5.1开始)。不支持int和string的传统类型提示。”错误是令人困惑的,因为你选择了“字符串”-把“myClass”放在它的位置,错误将读不同:“传递给phpwtf()的参数1必须是myClass的一个实例,字符串给定”
正如其他人已经说过的,类型提示目前只适用于对象类型。但我认为您触发的特定错误可能是在准备即将到来的字符串类型SplString。
理论上,它的行为像一个字符串,但由于它是一个对象,将通过对象类型验证。不幸的是,PHP 5.3中还没有,可能会在5.4中出现,所以还没有测试。
也许不安全也不漂亮,但如果你一定要:
class string
{
private $Text;
public function __construct($value)
{
$this->Text = $value;
}
public function __toString()
{
return $this->Text;
}
}
function Test123(string $s)
{
echo $s;
}
Test123(new string("Testing"));
由于PHP 7.0的类型声明允许标量类型,所以现在可以使用这些类型:self, array, callable, bool, float, int, string。前三个是在PHP 5中提供的,但后四个是在PHP 7中新增的。如果你使用任何其他的(例如整数或布尔),将被解释为类名。
有关更多信息,请参阅PHP手册。
(最初由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中,字符串可以是字符串,除非它实际上是字符串。与任何使用隐式类型转换的语言一样,上下文就是一切。