2

I've got to move a web site (custom-written (not by me), so just updating a CMS is not an option) to a PHP 5.3 server. The code complains::


Fatal error: Method cDate::__tostring() cannot take arguments in ...\lib.datetime.php on line 183

I've googled to find out that the problem is because "with PHP 5.3 the magic method __tostring() no more accepts any parameter", "... implements its __tostring() by accepting parameter ... which is now deprecated in favor of the new __tostring() for PHP 5.3". Here's the code:


public function __toString($format = 'Y-m-d')
{
  // the next is the line #182, the line #183 mentioned in the error message is the closing brace
  return date($format, $this->_stamp);
}

Is there something like a php.ini parameter I can tweak to bring this back to work?

I am not a PHP developer, neither I am too much willing to dive into studying and modifying the code which was written by some web dev outsourcing company in the past of the company I work for. My task is to move the web site from a shared hosting provider to a dedicated server which I admin (I run Ubuntu 10.04 LTS Server there) and which I'd strongly prefer not to downgrade to PHP 5.2. It would be great If I could just make it work with some configuration magic. I am afraid that if I modify a method, then the entire thing is going to stop working as expected.

Kara
  • 6,115
  • 16
  • 50
  • 57
Ivan
  • 63,011
  • 101
  • 250
  • 382
  • There was a ini parameter for forcing 4 compatibility, but it was removed. – powtac Mar 10 '11 at 14:02
  • 1
    Normally __toString() is not called directly. It is used in the class to decide what to do when the object is casted as string. So the question is, what is the purpose of your __toString() method? – powtac Mar 10 '11 at 14:05
  • 2
    I don't think sticking in deprecated behaviors is the way to go, maybe you should consider updating your code finding another way to accomplish the same task. – Terseus Mar 10 '11 at 14:06

2 Answers2

4

You cannot make __toString() accept parameters again. The method signature needs to be shallow. (I agree that is a needless deprecation, and why they didn't just throw an E_DEPRECATED instead of generating a fatal incompatibility is not very sensible.)

The only workaround is utilizing func_get_args() in lieu of real parameters:

class EmptyString { 
    function __toString() {
        print_r(func_get_args());
        return "";
    }
}

That will make 5.3 call the implicit __toString for "$so";, but still allow a manual $so->__toString(_WITH, "params");.

This scheme does not allow for the simplicity of parameter defaults of course. And since your goal is to get a legacy app working, it is insufficient. You need to implement this workaround in a base class, and adapt existing __toString methods into __oldString and have that invoked in compat mode. There is no way around a bit of rewriting.


Without any complicated wrapper methods, your specific example code adapted:

public function __toString()
{
    $format = func_get_arg(0)   or   $format = 'Y-m-d';

    return date($format, $this->_stamp);
}
mario
  • 144,265
  • 20
  • 237
  • 291
  • Thanks. I've added the code into the question body. It looks very simple, but I don't know how can I modify it to comply to PHP 5.3 and still work exactly as it is expected (by all the other code which can rely on it). – Ivan Mar 10 '11 at 14:30
  • It is not deprecated because it was already there since PHP5 and before that is was on the list of protected function names. – powtac Mar 10 '11 at 14:50
  • @powtac: That remark wasn't about deprecating the function use itself, but throwing a warning for extraneous parameters. (Instead of a fatal error.) – mario Mar 10 '11 at 14:54
2

If the problem is only in this class you can update the code of that class.

Create an override method __toString(), which accept parameters, that call is parent or completely rewrite the code of the method (I think it's not so hard).

But for more informations, we need some portion of code to sse the problem in context.

EDIT: Ok, I think the better solution is:

  1. rename the method and all his call. Because, the __toString is reserved to the magick method: printDate($fomat='Y-m-d').
  2. add an new method __toString() that call your printDate()

And use:

public function __toString()
{
    $format = isset(func_get_arg(0) ? func_get_arg(0) : 'Y-m-d';
    return date($format, $this->_stamp);
}
Akarun
  • 3,220
  • 2
  • 24
  • 25
  • I've added the code into the question body. It looks very simple, but I don't know how can I modify it to comply to PHP 5.3 and still work exactly as it is expected (by all the other code which can rely on it). – Ivan Mar 10 '11 at 14:29