我有一个函数,它期望一个字符串作为输入参数:
<?php
declare(strict_types = 1);
function testXml(string $xml) {
echo "this is a string: " .$xml;
}
当我传递一个对象给这个函数时,我希望会抛出一个类型错误。 但事实并非如此,类型为SimpleXmlElement的对象被默默转换为字符串: https://3v4l.org/lQdaZ 这是一个错误还是特性?
我有一个函数,它期望一个字符串作为输入参数:
<?php
declare(strict_types = 1);
function testXml(string $xml) {
echo "this is a string: " .$xml;
}
__toString()
的文档所述:
因为类
__toString()
方法允许类在被当作字符串处理时决定如何响应。
SimpleXmlElement
实现了__toString()
魔术方法,所以每次使用期望字符串的位置时都会调用它(该方法)。__toString()
返回的值将代替对象。testXml()
当前期望一个字符串作为参数,但你不喜欢它悄无声息地接受一个SimpleXmlElement
。__toString()
的调用,函数内$xml
参数的值是SimpleXmlElement
对象。在echo "this is a string: " .$xml;
行中发生了对__toString()
的调用,即使$xml
不是字符串,你也可以打印其值,这非常方便。echo
(期望字符串作为参数)应该抱怨$xml
的类型,并且不应该打印它。不太方便,对吧?
1 这不是一个错误,这就是语言发展的方式。__toString()
在标量类型的类型声明之前被引入,为了不破坏现有行为,如果可能的话会调用它,而不是触发有关参数类型不正确的错误。
declare(strict_types = 1);
执行OP的代码将以意外的方式工作。请参阅:https://3v4l.org/r7eL6 - k0pernikus这是一个 PHP 中的特性,如果定义了对象的 __toString
魔术方法,PHP 就会调用它:
此代码需要 PHP@7:
<?php
class ClassImplementingToString
{
public function __toString()
{
return "hello world";
}
}
function foo(string $foo)
{
echo $foo;
}
foo(new ClassImplementingToString());
将输出:你好,世界
Fatal error: Uncaught TypeError: Argument 1 passed to foo() must be of the type string, object given
- AndreKR__toString()
没有任何关系。即使一个具有 __toString()
方法的对象也不能被传递到期望字符串的位置。 - AndreKRdeclare(strict_types = 1);
。 - AndreKR
__toString()
无关。即使是具有__toString()
方法的对象也不能传递到期望字符串的位置。 - AndreKR