Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP 7 strict type object to string conversion

Tags:

php

I have a function which expects a string as input parameter:

<?php
declare(strict_types = 1);

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

Now when I feed this function an object, I expect a Type Error to be thrown. But this is not the case, an object of type SimpleXmlElement is silently converted to a string: https://3v4l.org/lQdaZ

Is this a bug or a feature?

like image 796
dev0 Avatar asked Sep 03 '25 02:09

dev0


2 Answers

As the documentation of the magic function __toString() explains:

The __toString() method allows a class to decide how it will react when it is treated like a string.

Because the class SimpleXmlElement implements the __toString() magic method, it (the method) is invoked every time a SimpleXmlElement is used where a string is expected. The value returned by __toString() is used instead of the object.

It is difficult to tell if this is a feature or a bug1. The function testXml() currently expects a string as argument and you are not pleased by the fact that it silently accepts a SimpleXmlElement instead.

If you remove the type of its argument, the call to __toString() does not happen any more and the value of the $xml argument inside the function is the SimpleXmlElement object. The call to __toString() happens in the echo "this is a string: " .$xml; line and it's very convenient that you can print the value of $xml even if it is not a string.

If you think it is a bug then echo (which expects strings as arguments) should complain about the type of $xml and should not print it. Not that convenient, isn't it?


1 It is not a bug, this is how the language evolved. __toString() was introduced before type declarations for scalar types and, in order to not break the existing behaviour, it is invoked if it's possible instead of triggering an error about incorrect type of the argument.

like image 118
axiac Avatar answered Sep 07 '25 14:09

axiac


That is because you are passing the string ($simpleXml) and not the SimpleXmlElement ($xml) to the function.

like image 35
AndreKR Avatar answered Sep 07 '25 13:09

AndreKR