Warning about PHP 5.2.4 and Creole

September 13, 2007

WarningIt’s almost half a month ago since PHP 5.2.4 was released and since I really like to update software ;-) I immediately upgraded from 5.2.3 – but the result was rather shocking – all my Symfony projects stopped working because of a Exception thrown by Propel: “Error populating Pages object [wrapped: Unable to convert value at column 13 to timestamp: 0000-00-00 00:00:00]“.

I watched the Symfony forums/mailing lists and the Propel mailing lists, but nothing similar was posted so that i tracked it down on my own and found the issue in Creole (DBAL used by Propel, which is used by Symfony).

The issue lies in the getTimestamp() function (Line 126 in creole/drivers/mysql/MySQLResultSet.php), which basically just converts a date from your database to a unix timestamp.Let’s say that your database field has the default value “0000-00-00 00:00:00” set on a datetime field and the getTimestamp() function tries to parse this default value with strtotime, which worked fine in PHP 5.2.3 and below since this function would return “943905600” (which equals to 1999-11-30, but don’t ask me why…) but was fixed in PHP 5.2.4. The function now returns boolean FALSE which is causing the function to fail and throw an Exception.

It’s okay that strtotime doesn’t accept “0000-00-00 00:00:00” as a date and returns false instead, but since this value is often used as a default for a datetime field in Propel and will break your application(s).Unfortunately Creole is not actively maintained anymore, so don’t expect a fix for this issue, but you can of course fix it yourself like this:

if ($this->fields[$column] == '0000-00-00 00:00:00') {    // If the value is  '0000-00-00 00:00:00', set it back to the value strtotime() returned before PHP 5.2.4    $ts = '943916400';}else {    $ts = strtotime($this->fields[$column]);}

You can try the fix and work with Symfony and PHP 5.2.4, but I will go back to PHP 5.2.3 since i can’t be 100% sure that there is another error somewhere.Please state your opinion in the comments, thanks!

Update: Seth Wilson found another instance of this bug in \pear\symfony\vendor\creole\common\ResultSetCommon.php at line 356:

if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE throw new SQLException("Unable to convert value at column " . $column . " to timestamp: " . $this->fields[$idx]);}

To fix it, just change it to :

if ($ts === -1 || $ts === false) { // in PHP 5.1 return value changes to FALSE  return '943916400';  #throw new SQLException("Unable to convert value at column " . $column . " to timestamp: " . $this->fields[$idx]);}

Thanks Seth!

Update 2: Symfony 1.0.9 fixes this problem, be sure to upgrade!


15 Responses to “Warning about PHP 5.2.4 and Creole”

  1. […] Fuente: Warning about PHP 5.2.4 and Creole […]

  2. Brian Says:

    I’m getting really sick of these changes in even minor version releases of PHP. What will the PHP community do next to hurt itself? They’ve already done magic slashes, register globals, etc… It’s nearly impossible to write portable PHP code. I only use PHP when the client insists these days.

  3. Kevin Says:

    Does using null instead of 0000-00-00 00:00:00 as your default datetime value help?

  4. symfoniac Says:

    Hi Kevin, i will test that later when i have time. Thanks for the idea.

  5. Pete W Says:

    I allowed the date fields to be null and I cleared the default from the schema and the problem was resolved.

  6. Dejan Spasic Says:

    What about the default value 0000-00-00?

    if ($this->fields[$column] == ‘0000-00-00′ || $this->fields[$column] == ‘0000-00-00 00:00:00′) {

  7. Clint Byrum Says:

    I don’t think this is such a shocking change. They fixed a bug.. and Creole was relying on the broken behavior, without even knowing it. I believe the 1999-11-30 date was just due to binary truncation or wraparound.

    I’d say fix your data. 0000-00-00 00:00:00 is not a valid date on the gregorian calendar, which starts at 0001-01-01 00:00:00), before “fixing” the app.

  8. Stefan Says:

    Yeah, I also encountered this issue when I just upgraded my dotdeb php version.

    By the way, passing null values will solve the problem. However, all database datetime and date fields are by default NOT NULL fields it seems, instead opting for the default 0000-00-00 (00:00:00) notation.

    I’ve got a bigger problem though: for some reason my symfony commandline is also gone. It segfaults on anything I try.

  9. Stefan Says:

    And to extend the datetime solution (as I still had problems after fixing with the above), Creole has the same problem with DATE fields. This can be fixed in the ResultSetCommon.php:

    if ($this->fields[$idx] == ‘0000-00-00’) {
    $ts = ‘943916400’;
    } else {
    $ts = strtotime($this->fields[$idx]);

    instead of

    $ts = strtotime($this->fields[$idx]);

    Unfortunately, this does not yet resolve my CLI problems (hadn’t expected it to though)

  10. Stefan Says:

    OK, the CLI problem seems to have been caused by the Suhosin patch (at least for my machine, with my configuration, and the dotdeb repositories).

    Turning it off (won’t need it locally anyway) solved the problem.

  11. Chris Says:

    you guys rock! thanks for writing this entry. really appreciate it.

  12. Rafael Garcia Says:

    Im having the same error, and im using the latest symfony and propel versions, but my problem seems to be that im using sql server, and the equivalent for propel timestamp is the sql server datetime, I somehow managed to fix it for 1 of my project’s modules, but i cant fix it for the rest of them, any suggestions? plz emailme…

  13. RaiulBaztepo Says:

    Very Interesting post! Thank you for such interesting resource!
    PS: Sorry for my bad english, I’v just started to learn this language ;)
    See you!
    Your, Raiul Baztepo

  14. Esteban Says:

    Excellent solution. Very useful. Thanks.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: