php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #40799 change string conversion behaviour for objects not implementing __toString()
Submitted: 2007-03-14 03:51 UTC Modified: 2016-12-31 00:01 UTC
Votes:28
Avg. Score:4.5 ± 0.9
Reproduced:23 of 23 (100.0%)
Same Version:11 (47.8%)
Same OS:15 (65.2%)
From: oliver dot graetz at gmx dot de Assigned:
Status: Open Package: Scripting Engine problem
PHP Version: 5.2.1 OS: any
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: oliver dot graetz at gmx dot de
New email:
PHP Version: OS:

 

 [2007-03-14 03:51 UTC] 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

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-02-16 22:24 UTC] none at mialinator dot com
just fix datetime!
 [2011-09-09 11:26 UTC] 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?
 [2012-02-09 01:57 UTC] kavi at postpro dot net
Open for almost five years now without a single comment from a core developer.
 [2016-12-31 00:01 UTC] cmb@php.net
-Package: Feature/Change Request +Package: Scripting Engine problem
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC