Req #40799 [Com]: change string conversion behaviour for objects not implementing __toString()
Edit report at https://bugs.php.net/bug.php?id=40799&edit=1
ID: 40799
Comment by: oliver dot graetz at gmx dot de
Reported by: oliver dot graetz at gmx dot de
Summary: change string conversion behaviour for objects not
implementing __toString()
Status: Open
Type: Feature/Change Request
Package: Feature/Change Request
Operating System: any
PHP Version: 5.2.1
Block user comment: N
Private report: N
New Comment:
First of all: Fixing the DateTime class is a good start but this is really just one of many
problems.
Four and a half years have passed and with the current PHP the problem still persists: Put any
object not implementing __toString() into code where it is converted to string (for example using
"implode()") and you get a catchable fatal error.
PHP is a language ultimately designed to produce strings in 99.999% of all calls to any PHP script.
Introducing language changes that make this harder is not a good idea.
There are many situations when code runs through a list or hierarchy of variables. The current
situation forces the programmer to check whether a cast to string for any variables is safe:
$printable = (!is_object($var) or method_exists($var, '__toString'));
This is really a joke on its own: For arrays and even resources there is a fallback (e.g.
"Resource id #17"), only for objects someone decided that it would be a good idea to
instead produce catchable fatal errors under certain circumstances.
For me there currently remain some questions:
1. Why is there still no output for engine internal classes like DateTime where there is good reason
to actually provide a default output?
2. Why is there no "is_printable($var)" function if PHP changed to a language where not
all variables can be printed? The above code should not be needed to answer such a basic question.
Thinking about a "Printable" interface would also be a good idea if the current situation
with triggering errors remains.
3. Why is there a fallback "Array" for arrays but not "Object" or something else
for objects not providing the __toString method?
4. Why does this have to be a catchable fatal error that forces the programmer to provide an error
handler that purposely ignores it to continue script execution? Wouldn't an E_WARNING have
sufficed?
Previous Comments:
------------------------------------------------------------------------
[2010-02-16 22:24:56] none at mialinator dot com
just fix datetime!
------------------------------------------------------------------------
[2007-03-14 03:51:50] oliver dot graetz at gmx dot de
Description:
------------
Yes, I read the upgrade guide and the other bug reports regarding this topic so this is not a bug
report but a plea for reconsideration.
I really like that finally __toString() works in every situation but the inability to output object
instances without __toString() defined is just too annoying. PHP preaches the KISS principle and on
this issue the language is breaking its own rules.
First of all, there are engine internal classes where the programmer is unable to provide a
__toString method. Subclassing all of these classes upon usage just "to be on the safe
side" is nonsense. If object output can't be changed to provide a fallback if __toString()
is missing then at least all engine internal classes should implement their own default output.
Secondly, for safety many programmers might be tempted to make all classes extend a common
superclass just "to be on the safe side". This is braindead for the sake of any OOP
concept but I already see some guys on the horizon ready to do it.
And at last: There are so many convenient functions that just break if their input contains
"problem objects". It just makes no sense that PHP forces me to implement an "object
safe" version of implode()! I just had to do that and the loss of performance makes me shudder.
Rasmus once said that PHP should only be a frontend for "PHP templates" that make use of
as much precompiled code as possible. So why are these "templates" forced to implement
ever more stuff in the userland?
Suggestions:
- at least implement default output for all engine internal classes
- change __toString() to have a fallback, even "[__toString() missing]" improves on the
current situation
-- if this isn't POSSIBLE: PLEASE clearly state why at prominent places in the documentation.
-- if this isn't WANTED: make it configurable or better, add a magic function, for example
__tostring_fallback(), which should return a string. If it doesn't exist or doesn't return
a string: go ahead raising the recoverable error! Abusing an error handler to do this is NOT a
solution.
Reproduce code:
---------------
<?php
echo new DateTime();
/*
* How about this yielding the ISO formatted date or a timestamp?
* Possibly even as debug output like
*
* [DateTime object: 2004-02-12T15:19:21+00:00]
*
* Definitely better than raising an error!
*/
Expected result:
----------------
some output and the script continuing
Actual result:
--------------
PHP Catchable fatal error: Object of class DateTime could not be converted to string in C:\test.php
on line 2
Catchable fatal error: Object of class DateTime could not be converted to string in C:\test.php on
line 2
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=40799&edit=1
Thread (5 messages)