date() behaviour changed in 5.1?

php.internals

Sean Coates

20 years ago
I discussed this with Rasmus and Derick, yesterday, but I don't think we came to a conclusion.. Is this a bug, or intended behaviour? sean@iconoclast:~$ /opt/src/php-5.0.4/sapi/cli/php -r 'echo date("r", "1132003418 ") ."\n";' Mon, 14 Nov 2005 16:23:38 -0500 sean@iconoclast:~$ /opt/src/php5-200511131530/sapi/cli/php -r 'echo date("r", "1132003418 ") ."\n";' Warning: date() expects parameter 2 to be long, string given in Command line code on line 1 sean@iconoclast:~$ The conclusion SEEMED to be that it's a bug in the parameter parsing API (as date() now uses the new API). I think that the 2nd param should automatically be cast to an int. Yes, I realize that the documentation says it should be an int, and I'm ok with that (the extraneous whitespace is my fault). I think it should be mentioned in the release docs if it won't be fixed, though. Also, a warning is pretty harsh. A E_NOTICE is more representative of what's happening. Also, in the E_WARNING scenario above, date() no longer returns the expected result (based on <=5.0 code). So: is this a bug? If so, I can send a report -- I just didn't want it to get bogussed without discussion. If not -- I really think this should be fixed before 5.1.. I realize it's very late in the game, though. Opinions? S

Jani Taskinen

20 years ago
If you pass bad data to a function, it should not warn you? I'd rather have it as a FATAL error. :) Nothing to fix here, move along. (and fix your code..) --Jani On Tue, 15 Nov 2005, Sean Coates wrote:

Pierre Joye

20 years ago
On Tue, 15 Nov 2005 18:59:32 +0200 (EET) sniper@iki.fi (Jani Taskinen) wrote:
> > If you pass bad data to a function, it should not warn you? > I'd rather have it as a FATAL error. :) > > Nothing to fix here, move along. (and fix your code..)
PHP is losely typed, I see nothing wrong to pass an integer as string there (for example, imagecreate("100", "100"); works). --Pierre

Sean Coates

20 years ago
Pierre wrote:
> On Tue, 15 Nov 2005 18:59:32 +0200 (EET) > sniper@iki.fi (Jani Taskinen) wrote: > > >> If you pass bad data to a function, it should not warn you? >> I'd rather have it as a FATAL error. :) >> >> Nothing to fix here, move along. (and fix your code..) > > > PHP is losely typed, I see nothing wrong to pass an integer as string > there (for example, imagecreate("100", "100"); works).
FWIW, I don't mind forcing an INT here (or an all-numeric string) -- I know my code was wrong; I admitted this in the first mail. We need to warn users about it, if we do, though. I'm only bringing this up because the behaviour _changed_ from 5.0 S

Rasmus Lerdorf

20 years ago
Pierre wrote:
> On Tue, 15 Nov 2005 18:59:32 +0200 (EET) > sniper@iki.fi (Jani Taskinen) wrote: > >> If you pass bad data to a function, it should not warn you? >> I'd rather have it as a FATAL error. :) >> >> Nothing to fix here, move along. (and fix your code..) > > PHP is losely typed, I see nothing wrong to pass an integer as string > there (for example, imagecreate("100", "100"); works).
The question isn't what to do with "100","100" but what to do with "100abc","100abc". Should that still work? The old zend_get_parameters() following by a convert_to_long() says Yes. The newer zend_parse_parameters() says no. -Rasmus

Pierre Joye

20 years ago
On Tue, 15 Nov 2005 09:17:20 -0800 rasmus@lerdorf.com (Rasmus Lerdorf) wrote:
> Pierre wrote: > > On Tue, 15 Nov 2005 18:59:32 +0200 (EET) > > sniper@iki.fi (Jani Taskinen) wrote: > > > >> If you pass bad data to a function, it should not warn you? > >> I'd rather have it as a FATAL error. :) > >> > >> Nothing to fix here, move along. (and fix your code..) > > > > PHP is losely typed, I see nothing wrong to pass an integer as > > string there (for example, imagecreate("100", "100"); works). > > The question isn't what to do with "100","100" but what to do with > "100abc","100abc". Should that still work? The old > zend_get_parameters() following by a convert_to_long() says Yes. The > newer zend_parse_parameters() says no.
My answer was to Jani's. --Pierre

Rasmus Lerdorf

20 years ago
Pierre wrote:
> On Tue, 15 Nov 2005 09:17:20 -0800 > rasmus@lerdorf.com (Rasmus Lerdorf) wrote: > >> Pierre wrote: >>> On Tue, 15 Nov 2005 18:59:32 +0200 (EET) >>> sniper@iki.fi (Jani Taskinen) wrote: >>> >>>> If you pass bad data to a function, it should not warn you? >>>> I'd rather have it as a FATAL error. :) >>>> >>>> Nothing to fix here, move along. (and fix your code..) >>> PHP is losely typed, I see nothing wrong to pass an integer as >>> string there (for example, imagecreate("100", "100"); works). >> The question isn't what to do with "100","100" but what to do with >> "100abc","100abc". Should that still work? The old >> zend_get_parameters() following by a convert_to_long() says Yes. The >> newer zend_parse_parameters() says no. > > My answer was to Jani's.
I realize that, but Jani said "bad data" not data of the wrong type. Your example didn't have any bad data. You just had "100" which is a perfectly valid numeric string and will work in all cases. -Rasmus

Pierre Joye

20 years ago
On Tue, 15 Nov 2005 09:29:29 -0800 rasmus@lerdorf.com (Rasmus Lerdorf) wrote:
>> my answer was to Jani's. > > I realize that, but Jani said "bad data" not data of the wrong type. > Your example didn't have any bad data. You just had "100" which is a > perfectly valid numeric string and will work in all cases.
The point is still valid. I believe there is will be enough changes in 5.1 in the date area without this one. I do not consider trailing white chars as invalid (especially not spaces). It is common to pass those values directly from a database results, results can sometimes use fixed length strings. --Pierre

Jani Taskinen

20 years ago
On Tue, 15 Nov 2005, Rasmus Lerdorf wrote:
> > Pierre wrote: >> On Tue, 15 Nov 2005 18:59:32 +0200 (EET) >> sniper@iki.fi (Jani Taskinen) wrote: >> >>> If you pass bad data to a function, it should not warn you? >>> I'd rather have it as a FATAL error. :) >>> >>> Nothing to fix here, move along. (and fix your code..) >> >> PHP is losely typed, I see nothing wrong to pass an integer as string >> there (for example, imagecreate("100", "100"); works). > > The question isn't what to do with "100","100" but what to do with > "100abc","100abc". Should that still work? The old zend_get_parameters() > following by a convert_to_long() says Yes. The newer zend_parse_parameters() > says no.
With new version it's possible to catch such typos, with old one they'd just be silently ignored and perhaps could cause very hard to find bugs in your code.. --Jani

Rasmus Lerdorf

20 years ago
Jani Taskinen wrote:
> On Tue, 15 Nov 2005, Rasmus Lerdorf wrote: > >> >> Pierre wrote: >>> On Tue, 15 Nov 2005 18:59:32 +0200 (EET) >>> sniper@iki.fi (Jani Taskinen) wrote: >>> >>>> If you pass bad data to a function, it should not warn you? >>>> I'd rather have it as a FATAL error. :) >>>> >>>> Nothing to fix here, move along. (and fix your code..) >>> >>> PHP is losely typed, I see nothing wrong to pass an integer as string >>> there (for example, imagecreate("100", "100"); works). >> >> The question isn't what to do with "100","100" but what to do with >> "100abc","100abc". Should that still work? The old >> zend_get_parameters() following by a convert_to_long() says Yes. The >> newer zend_parse_parameters() says no. > > With new version it's possible to catch such typos, with old one they'd > just be silently ignored and perhaps could cause very hard to find > bugs in your code..
I suppose, but I still find it weird that: date("h", (int)$foo); and date("h", $foo); will behave differently when $foo isn't a clean numeric string. And when we move 100% to zend_parse_parameters() in PHP 6 there will be many more functions changing their behaviour due to this. -Rasmus

Jani Taskinen

20 years ago
On Tue, 15 Nov 2005, Rasmus Lerdorf wrote:
> > Jani Taskinen wrote: >> On Tue, 15 Nov 2005, Rasmus Lerdorf wrote: >> >>> >>> Pierre wrote: >>>> On Tue, 15 Nov 2005 18:59:32 +0200 (EET) >>>> sniper@iki.fi (Jani Taskinen) wrote: >>>> >>>>> If you pass bad data to a function, it should not warn you? >>>>> I'd rather have it as a FATAL error. :) >>>>> >>>>> Nothing to fix here, move along. (and fix your code..) >>>> >>>> PHP is losely typed, I see nothing wrong to pass an integer as string >>>> there (for example, imagecreate("100", "100"); works). >>> >>> The question isn't what to do with "100","100" but what to do with >>> "100abc","100abc". Should that still work? The old zend_get_parameters() >>> following by a convert_to_long() says Yes. The newer >>> zend_parse_parameters() says no. >> >> With new version it's possible to catch such typos, with old one they'd >> just be silently ignored and perhaps could cause very hard to find bugs >> in your code.. > > I suppose, but I still find it weird that: > > date("h", (int)$foo); > > and > > date("h", $foo); > > will behave differently when $foo isn't a clean numeric string. And when we > move 100% to zend_parse_parameters() in PHP 6 there will be many more > functions changing their behaviour due to this.
I bet this isn't only thing that's changing. But you really can't get an omelette without breaking some eggs, can you? :) --Jani

Wez Furlong

20 years ago
I can't think of any case where you'd want to error out when given '100 ' if it would accept '100' quite happily. I'd lean towards a single cast semantic for this, and remove that strict checking flag from zend_parse_parameters(); lazy dynamic type handling for primitive data types is one of the cornerstones of PHP IMO. --Wez. On 11/15/05, Rasmus Lerdorf <rasmus@lerdorf.com> wrote:

Rasmus Lerdorf

20 years ago
Wez Furlong wrote:
> I can't think of any case where you'd want to error out when given > '100 ' if it would accept '100' quite happily. > > I'd lean towards a single cast semantic for this, and remove that > strict checking flag from zend_parse_parameters(); lazy dynamic type > handling for primitive data types is one of the cornerstones of PHP > IMO.
Yeah, I am leaning towards that as well. I don't like the inconsistency between direct casting via (int) vs. zend_parse_parameter's strict casting. It is much simpler to explain that functions will cast to the required parameter type and have one consistent way to cast things. -Rasmus

Lukas Smith

20 years ago
Rasmus Lerdorf wrote:
> Wez Furlong wrote: > >> I can't think of any case where you'd want to error out when given >> '100 ' if it would accept '100' quite happily. >> >> I'd lean towards a single cast semantic for this, and remove that >> strict checking flag from zend_parse_parameters(); lazy dynamic type >> handling for primitive data types is one of the cornerstones of PHP >> IMO. > > > Yeah, I am leaning towards that as well. I don't like the inconsistency > between direct casting via (int) vs. zend_parse_parameter's strict > casting. It is much simpler to explain that functions will cast to the > required parameter type and have one consistent way to cast things.
+1 this is really what i have come to expect from PHP (which is why I never understood why we changed array_merge to not cast null to an empty array back in PHP 5.0.0) regards, Lukas

Bob Silva

20 years ago
Would objects be included in this "one consistent way to cast things"? The old zend_get_parameters API works since the calling function was responsible for the conversions, but in the newer zend_parse_parameters API they get filtered out by the case statement on what "types" to pass into the convert_to_ function. My reasons for this are selfish and I don't know that it benefits the community in large, but you guys had the foresight to build in the cast_object and get/set handlers to fully support objects internally, would be nice to be able to pass them to functions as well. Right now, I also have to do the pre-cast to make it work with internal functions using the newer API to retrieve bool-long-double and arrays. And since PHP6 is moving completely to the newer API....I'm holding my breath to see what is done with the API to support objects since my extension is dependent on it. On a side note, are there instructions on how to PECL'ize an extension so I can release a first revision? Thanks Bob Silva

Jakub Vrana

20 years ago
Rasmus Lerdorf wrote:
> Yeah, I am leaning towards that as well. I don't like the inconsistency > between direct casting via (int) vs. zend_parse_parameter's strict > casting. It is much simpler to explain that functions will cast to the > required parameter type and have one consistent way to cast things.
I want be warned about wrong parameters. I (as a doc-guy) would rather describe strict and non-strict casting than not be warned about obviously wrong wordwrap("abc", "b"). I naturally agree with consistent parsing of parameters through zend_parse_parameters() - my script checking if parameters in source and documentation match uses it. Jakub Vrana

Rasmus Lerdorf

20 years ago
Jakub Vrana wrote:
> Rasmus Lerdorf wrote: >> Yeah, I am leaning towards that as well. I don't like the inconsistency >> between direct casting via (int) vs. zend_parse_parameter's strict >> casting. It is much simpler to explain that functions will cast to the >> required parameter type and have one consistent way to cast things. > > I want be warned about wrong parameters. I (as a doc-guy) would rather > describe strict and non-strict casting than not be warned about > obviously wrong wordwrap("abc", "b"). > > I naturally agree with consistent parsing of parameters through > zend_parse_parameters() - my script checking if parameters in source > and documentation match uses it.
Right now, without looking at the source code, there is no way to tell which functions do strict casting and which ones don't. -R

Andrei Zmievski

20 years ago
Perhaps, but I would maintain that passing "123abc" and having it interpreted as 123 is still wrong. -Andrei On Nov 15, 2005, at 9:42 AM, Wez Furlong wrote:

Derick Rethans

20 years ago
On Tue, 15 Nov 2005, Andrei Zmievski wrote:
> Perhaps, but I would maintain that passing "123abc" and having it interpreted > as 123 is still wrong.
Yeah, I lean that way too, although trailing whitespace should be supported IMO. regards, Derick
-- Derick Rethans http://derickrethans.nl | http://ez.no | http://xdebug.org

Rasmus Lerdorf

20 years ago
Derick Rethans wrote:
> On Tue, 15 Nov 2005, Andrei Zmievski wrote: > >> Perhaps, but I would maintain that passing "123abc" and having it interpreted >> as 123 is still wrong. > > Yeah, I lean that way too, although trailing whitespace should be > supported IMO.
I don't like having two different ways to cast things and I think we would break a lot of stuff if (int)"123abc" no longer resulted in 123. -Rasmus

Andrei Zmievski

20 years ago
Perhaps, but I would maintain that passing "123abc" and having it interpreted as 123 is still wrong. -Andrei On Nov 15, 2005, at 9:42 AM, Wez Furlong wrote:

Rasmus Lerdorf

20 years ago
Jani Taskinen wrote:
> > If you pass bad data to a function, it should not warn you? > I'd rather have it as a FATAL error. :) > > Nothing to fix here, move along. (and fix your code..)
The issue here is we effectively have two different casting mechanisms. One of the things we need to do when moving to PHP 6 is to make sure everything is using zend_parse_parameters() to handle function parameters. Most people would assume that a function that wasn't using zend_parse_parameters() before and was defined to take a long and thus passed the parameter through convert_to_long() wouldn't change its behaviour when moved to zend_parse_parameters() with an "l". That is: zval **foo; long lfoo; zend_get_parameters_ex(1, &foo) convert_to_long_ex(foo); lfoo = Z_LVAL_PP(foo); is not equivalent to: long foo; zend_parse_parameters(1, "l", &foo); In order to not change the behaviour of the function moving to zend_parse_parameters() from zend_get_parameters() you have to use a "z" and do the convert_to_long yourself. The reason for this is that is_numeric_string() has a flag called allow_errors which specifies whether or not it should be strict. When you cast from PHP or use one of the conversion functions internally this flag is off. When calling zend_parse_parameters it is on. I am not sure what the right answer here is. I can see the argument for being strict on parameter types, but at the same time, we will potentially be breaking a lot of existing code. And at a higher level I don't like the concept of having two different casting modes. -Rasmus