我有一个函数,它需要一个字符串作为输入参数:

<?php
declare(strict_types = 1);

function testXml(string $xml) {
    echo "this is a string: " .$xml;
}

现在,当我为这个函数提供一个对象时,我希望抛出一个类型错误。
但事实并非如此,SimpleXmlElement 类型的对象会被静默转换为字符串:
https://3v4l.org/lQdaZ

这是错误还是功能?

最佳答案

正如 magic function __toString() 的文档所解释的:



因为类 SimpleXmlElement 实现了 __toString() 魔术方法,所以每次在需要字符串的地方使用 SimpleXmlElement 时都会调用它(该方法)。使用 __toString() 返回的值代替对象。

很难判断这是一个特性还是一个 bug1。函数 testXml() 当前需要一个字符串作为参数,而您对它默默接受 SimpleXmlElement 的事实并不满意。

如果删除其参数的类型,则不会再调用 __toString() 并且函数内 $xml 参数的值是 SimpleXmlElement 对象。 __toString() 的调用发生在 echo "this is a string: " .$xml; 行中,即使 $xml 的值不是字符串,也可以很方便地打印它。

如果您认为这是一个错误,那么 echo (它需要字符串作为参数)应该提示 $xml 的类型并且不应该打印它。不是很方便吧?

1 这不是错误,这就是语言的演变方式。 __toString() 是在 type declarations 之前为标量类型引入的,为了不破坏现有行为,它会在可能的情况下被调用,而不是触发关于参数类型不正确的错误。

关于PHP 7 严格类型对象到字符串的转换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46766584/

10-14 15:23
查看更多