如何在 PHP 7 之前解决“必须是字符串的实例,给出的字符串”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4103480/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to resolve "must be an instance of string, string given" prior to PHP 7?
提问by leepowers
Here is my code:
这是我的代码:
function phpwtf(string $s) {
echo "$s\n";
}
phpwtf("Type hinting is da bomb");
Which results in this error:
这导致此错误:
Catchable fatal error: Argument 1 passed to phpwtf() must be an instance of string, string given
可捕获的致命错误:传递给 phpwtf() 的参数 1 必须是字符串的实例,给出的字符串
It's more than a little Orwellian to see PHP recognize and reject the desired type in the same breath. There are five lights, damn it.
看到 PHP 同时识别和拒绝所需的类型,这不仅仅是一点奥威尔式的。有五个灯,该死。
What is the equivalent of type hinting for strings in PHP? Bonus consideration to the answer that explains exactly what is going on here.
PHP 中字符串类型提示的等价物是什么?对准确解释这里发生的事情的答案的额外考虑。
采纳答案by deceze
Prior to PHP 7 type hintingcan only be used to force the types of objects and arrays. Scalar types are not type-hintable. In this case an object of the class string
is expected, but you're giving it a (scalar) string
. The error message may be funny, but it's not supposed to work to begin with. Given the dynamic typing system, this actually makes some sort of perverted sense.
在 PHP 7 之前,类型提示只能用于强制对象和数组的类型。标量类型不是类型提示的。在这种情况下,需要一个类的对象string
,但你给它一个 (scalar) string
。错误消息可能很有趣,但一开始就不应该起作用。鉴于动态类型系统,这实际上具有某种变态的意义。
You can only manually"type hint" scalar types:
您只能手动“输入提示”标量类型:
function foo($string) {
if (!is_string($string)) {
trigger_error('No, you fool!');
return;
}
...
}
回答by Yanick Rochon
From PHP's manual:
来自PHP 的手册:
Type Hints can only be of the object and array (since PHP 5.1) type. Traditional type hinting with int and string isn't supported.
类型提示只能是对象和数组(自 PHP 5.1 起)类型。不支持使用 int 和 string 的传统类型提示。
So you have it. The error message is not really helpful, I give you that though.
所以你有它。错误消息并不是很有帮助,但我还是给了你。
** 2017 Edit **
** 2017 编辑 **
PHP7 introduced more function data type declarations, and the aforementioned link has been moved to Function arguments : Type declarations. From that page :
PHP7 引入了更多的函数数据类型声明,上述链接已移至函数参数:类型声明。从该页面:
Valid types
- 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. 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)
Warning
Aliases for the above scalar types are not supported. Instead, they are treated as class or interface names. For example, using boolean as a parameter or return type will require an argument or return value that is an instanceof the class or interface boolean, rather than of type bool:
<?php function test(boolean $param) {} test(true); ?>
The above example will output:
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 5.0.0 起)
- self:参数必须是与定义方法的类相同的类的实例。这只能用于类和实例方法。(自 PHP 5.0.0 起)
- array:参数必须是一个数组。(PHP 5.1.0 起) 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 的实例。(自 PHP 7.1.0 起)
警告
不支持上述标量类型的别名。相反,它们被视为类或接口名称。例如,使用 boolean 作为参数或返回类型将需要一个参数或返回值,它是类或接口 boolean 的实例,而不是 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
The last warning is actually significant to understand the error "Argument must of type string, string given"; since mostly only class/interface names are allowed as argument type, PHP tries to locate a class name "string", but can't find any because it is a primitive type, thus fail with this awkward error.
最后一个警告对于理解错误“Argument must of type string,string given”实际上很重要;由于大多数情况下只允许类/接口名称作为参数类型,PHP 尝试定位类名称“字符串”,但无法找到任何,因为它是原始类型,因此失败并出现这个尴尬的错误。
回答by Surreal Dreams
PHP allows "hinting" where you supply a class to specify an object. According to the PHP manual, "Type Hints can only be of the object and array (since PHP 5.1) type. Traditional type hinting with int and string isn't supported." The error is confusing because of your choice of "string" - put "myClass" in its place and the error will read differently: "Argument 1 passed to phpwtf() must be an instance of myClass, string given"
PHP 允许“提示”您在何处提供类来指定对象。根据 PHP 手册,“类型提示只能是对象和数组(自 PHP 5.1 起)类型。不支持使用 int 和 string 的传统类型提示。” 由于您选择了“字符串”,错误令人困惑 - 将“myClass”放在其位置,错误将显示为不同的内容:“传递给 phpwtf() 的参数 1 必须是 myClass 的实例,给出字符串”
回答by mario
As others have already said, type hinting currently only works for object types. But I think the particular error you've triggered might be in preparation of the upcoming string type SplString.
正如其他人已经说过的,类型提示目前仅适用于对象类型。但我认为您触发的特定错误可能是为即将到来的字符串类型SplString做准备。
In theory it behaves like a string, but since it is an object would pass the object type verification. Unfortunately it's not yet in PHP 5.3, might come in 5.4, so haven't tested this.
理论上它的行为就像一个字符串,但因为它是一个对象,所以会通过对象类型验证。不幸的是,它还没有出现在 PHP 5.3 中,可能会出现在 5.4 中,因此尚未对此进行测试。
回答by TwoStraws
As of PHP 7.0 type declarations allow scalar types, so these types are now available: self
, array
, callable
, bool
, float
, int
, string
. The first three were available in PHP 5, but the last four are new in PHP 7. If you use anything else (e.g. integer
or boolean
) that will be interpreted as a class name.
从 PHP 7.0 开始,类型声明允许标量类型,因此这些类型现在可用:self
, array
, callable
, bool
, float
, int
, string
。前三个在 PHP 5 中可用,但后四个在 PHP 7 中是新的。如果您使用其他任何东西(例如integer
或boolean
),将被解释为类名。
回答by TwoStraws
(originally posted by leepowersin his question)
(最初由leepowers在他的问题中发布)
The error message is confusing for one big reason:
错误消息令人困惑的一个重要原因是:
Primitive type names are not reserved in PHP
PHP 中不保留原始类型名称
The following are all valid class declarations:
以下是所有有效的类声明:
class string { }
class int { }
class float { }
class double { }
My mistake was in thinking that the error message was referring solely to the string primitive type - the word 'instance' should have given me pause. An example to illustrate further:
我的错误是认为错误消息仅指字符串原始类型 - “实例”这个词应该让我停下来。一个进一步说明的例子:
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')]);
Output:
输出:
$s1 - primitive string? yes - string instance? no
$s2 - primitive string? no - string instance? yes
$s1 - 原始字符串?是 - 字符串实例?不
$s2 - 原始字符串?没有 - 字符串实例?是的
In PHP it's possible for a string
to be a string
except when it's actually a string
. As with any language that uses implicit type conversion, context is everything.
在 PHP 中,a 可能string
是 a,string
除非它实际上是string
. 与使用隐式类型转换的任何语言一样,上下文就是一切。
回答by Patrick
Maybe not safe and pretty but if you must:
也许不安全和漂亮,但如果你必须:
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"));
回答by ecairol
I got this error when invoking a function from a Laravel Controller to a PHP file.
从 Laravel 控制器调用函数到 PHP 文件时出现此错误。
After a couple of hours, I found the problem: I was using $thisfrom within a static function.
几个小时后,我发现了问题:我在静态函数中使用了$this。
回答by subosito
I think typecasting on php on inside block, String on PHP is not object as I know:
我认为在内部块上对 php 进行类型转换,PHP 上的 String 不是我所知道的对象:
<?php
function phpwtf($s) {
$s = (string) $s;
echo "$s\n";
}
phpwtf("Type hinting is da bomb");