Edit report at https://bugs.php.net/bug.php?id=40799&edit=1

 ID:                 40799
 Comment by:         kavi at postpro dot net
 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:

Open for almost five years now without a single comment from a core developer.


Previous Comments:
------------------------------------------------------------------------
[2011-09-09 11:26:38] oliver dot graetz at gmx dot de

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?

------------------------------------------------------------------------
[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

Reply via email to