Objects with __toString are not strings.

<?php
class foo {
  function
__toString() {
    return
"x";
  }
}
$foo = new foo;
var_dump(strpos($foo, "x"));
var_dump(strpos("x", $foo));
$array = array("x" => "y");
var_dump($array[$foo]);
var_dump($foo[0]);
?>

What's the output?

int(0)
PHP Notice: Object of class foo could not be converted to int in /tmp/x.php on line 8
PHP Warning: Illegal offset type in /tmp/x.php on line 11
PHP Fatal error: Cannot use object of type foo as array in /tmp/x.php on line 12

The first notice is because

If needle is not a string, it is converted to an integer and applied as the ordinal value of a character.

Things that are neither strings nor numbers can only cast to 0 or 1 when casted to integer and looking for chr(0) and chr(1) is not actually something you do often so that makes close to no sense anyways. But even if this rule makes some sense somehow, objects have no way to be cast into an integer on the other hand they can have a way to be cast to a string and so it'd only make sense to be cast to string but no. Five year old bug report at https://bugs.php.net/bug.php?id=48442 .

The second warning is because __toString() is not called automatically when the object is an array index. Again, logic would dictate to call it because only strings and integers are valid array indexes and again objects can only be cast into a string. Bug report at https://bugs.php.net/bug.php?id=54082

Finally, strings for a while had square brackets as array indexes then briefly curly brackets were endorsed then we returned to square brackets and here we are: PHP tries to use object as an array which doesn't work -- it could cast it to a string where it would work but nope.

Parting shot: php -r 'class x { function __toString() { return 1;}} $c = new x; print (string)$c;' is a PHP Catchable fatal error:  Method x::__toString() must return a string value . When did PHP become a strictly typed language...?