3v4l.org

run code in 300+ PHP versions simultaneously
<?php // // The goal is to try to safely cast an object to string but only if it can reasonably // be assumed to be stringable. (properly implements __toString) // // This is as close as I've been able to come to ensure that bad things do not get // called and I only deal with proper string results. // // The only major edge case here is that without implementing reflection it is // impossible to know if __toString was implemented as a static method. This // is a bummer but I'm willing to call this one "good enough." // class HasValidToString { public function __toString() { return 'Object\'s __toString is valid'; } } class HasNonPublicToString { protected function __toString() { return 'has non public __toString'; } } class HasNullToStringReturnValue { public static function __toString() { } } class HasNumberReturnValue { public function __toString() { return 5; } } class HasObjectReturnValue { public function __toString() { return new HasValidToString(); } } // Do to PHP's fuzzy nature on how to handle things like this, you'll get a warning that // this method should not be static but it will happily let you call it on an object // instance so even though you might say that this is expected to fail it actually // won't. Chances are something else awful will happen, though. Short of dipping // into Reflection I'm not sure how to guard against this such that we do not // call into a static __toString method. class HasStaticToString { public static function __toString() { return 'Object\'s __toString is static; should not be able to call it'; } } $isExpectedToPass = true; $isExpectedToFail = false; function safely_cast_object_to_string($object) { if (! method_exists($object, '__toString')) { throw new InvalidArgumentException('Object has no __toString'); } if (! is_callable([$object, '__toString'])) { throw new InvalidArgumentException('Object\'s __toString is not callable'); } $string = $object->__toString(); if (! is_string($string)) { throw new InvalidArgumentException('Object\'s __toString does not return a string value'); } return $string; } foreach ([ [new HasValidToString(), $isExpectedToPass], [new HasNonPublicToString(), $isExpectedToFail], [new HasNullToStringReturnValue(), $isExpectedToFail], [new HasNumberReturnValue(), $isExpectedToFail], [new HasObjectReturnValue(), $isExpectedToFail], [new HasStaticToString(), $isExpectedToFail], // it actually passes... ] as $test) { list ($sample, $expectation) = $test; $actual = false; $string = null; $message = ''; try { $string = safely_cast_object_to_string($sample); $actual = true; } catch (\InvalidArgumentException $e) { $message = $e->getMessage(); } printf( "%26s [%s] %s\n", get_class($sample), $actual === $expectation ? 'PASS' : 'FAIL', ! is_null($string) ? $string : $message ); }
Output for 8.0.0 - 8.0.30, 8.1.0 - 8.1.28, 8.2.0 - 8.2.18, 8.3.0 - 8.3.4, 8.3.6
Warning: The magic method HasNonPublicToString::__toString() must have public visibility in /in/nsetu on line 16 Fatal error: Method HasNullToStringReturnValue::__toString() cannot be static in /in/nsetu on line 17
Process exited with code 255.
Output for 8.3.5
Warning: PHP Startup: Unable to load dynamic library 'sodium.so' (tried: /usr/lib/php/8.3.5/modules/sodium.so (libsodium.so.23: cannot open shared object file: No such file or directory), /usr/lib/php/8.3.5/modules/sodium.so.so (/usr/lib/php/8.3.5/modules/sodium.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 Warning: The magic method HasNonPublicToString::__toString() must have public visibility in /in/nsetu on line 16 Fatal error: Method HasNullToStringReturnValue::__toString() cannot be static in /in/nsetu on line 17
Process exited with code 255.
Output for 5.5.0 - 5.5.38, 5.6.0 - 5.6.38, 7.0.0 - 7.0.33, 7.1.0 - 7.1.25, 7.2.0 - 7.2.33, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33
Warning: The magic method __toString() must have public visibility and cannot be static in /in/nsetu on line 16 Warning: The magic method __toString() must have public visibility and cannot be static in /in/nsetu on line 17 Warning: The magic method __toString() must have public visibility and cannot be static in /in/nsetu on line 28 HasValidToString [PASS] Object's __toString is valid HasNonPublicToString [PASS] Object's __toString is not callable HasNullToStringReturnValue [PASS] Object's __toString does not return a string value HasNumberReturnValue [PASS] Object's __toString does not return a string value HasObjectReturnValue [PASS] Object's __toString does not return a string value HasStaticToString [FAIL] Object's __toString is static; should not be able to call it

preferences:
226.08 ms | 404 KiB | 293 Q