Fw: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
If Z_TYPE_P(length_param) is 0, it's not NULL because it has something in it. Bleh... but you know what I mean :) -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
There's an IS_NULL check... if (ZEND_NUM_ARGS() = 3 Z_TYPE_P(length_param) != IS_NULL) { If Z_TYPE_P(length_param) is 0, it's not NULL because it has something in it. If length_param were of type long and had a value of 0, it would be NULL. Ouch... Now I see. Is there anybody using this trick, provided it never was documented? This is *so* wrong. The manual kind of skirts around it: If length is given and is positive, then the sequence will have that many elements in it. If length is given and is negative then the sequence will stop that many elements from the end of the array. If it is omitted, then the sequence will have everything from offset up until the end of the array . Meaning, basically, -1 is the same as omitted and the same as null? -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
The manual kind of skirts around it: If length is given and is positive, then the sequence will have that many elements in it. If length is given and is negative then the sequence will stop that many elements from the end of the array. If it is omitted, then the sequence will have everything from offset up until the end of the array . Meaning, basically, -1 is the same as omitted and the same as null? No, that works as it says in the manual. -1 is one short of all elements. The only thing the manual doesn't say is what it means by 'omitted', so it's down to whether anyone's found 0 useful when it acts as it always has. If they haven't, we can move to long and break any existing code that uses something other than an integer, but at least we'll be giving a warning about it. If they have, we don't have any option but to stay with the zval and fix it to work as it did up until last month. Warnings in that case would be an added extra. - Steph ps Sane patches attached for both the long version and the zval version (with no warnings). The current test for array_slice behaviour will need fixing whatever the decision is. Please ignore everything on the associated bug report.. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php Index: ext/standard/array.c === RCS file: /repository/php-src/ext/standard/array.c,v retrieving revision 1.308.2.21.2.37.2.11 diff -u -r1.308.2.21.2.37.2.11 array.c --- ext/standard/array.c5 Dec 2007 19:55:31 - 1.308.2.21.2.37.2.11 +++ ext/standard/array.c9 Dec 2007 23:07:13 - @@ -2120,6 +2120,7 @@ /* We want all entries from offset to the end if length is not passed or is null */ if (ZEND_NUM_ARGS() = 3 Z_TYPE_P(length_param) != IS_NULL) { + convert_to_long(length_param); length = Z_LVAL_P(length_param); } else { length = num_in; Index: ext/standard/array.c === RCS file: /repository/php-src/ext/standard/array.c,v retrieving revision 1.308.2.21.2.37.2.11 diff -u -r1.308.2.21.2.37.2.11 array.c --- ext/standard/array.c5 Dec 2007 19:55:31 - 1.308.2.21.2.37.2.11 +++ ext/standard/array.c10 Dec 2007 18:40:05 - @@ -2101,17 +2101,16 @@ zval *input,/* Input array */ **entry;/* An array entry */ long offset,/* Offset to get elements from */ -length;/* How many elements to get */ +length = 0;/* How many elements to get */ zend_bool preserve_keys = 0; /* Whether to preserve keys while copying to the new array or not */ int num_in,/* Number of elements in the input array */ pos; /* Current position in the array */ - zval*length_param; char *string_key; uint string_key_len; ulong num_key; HashPosition hpos; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, al|zb, input, offset, length_param, preserve_keys) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, al|lb, input, offset, length, preserve_keys) == FAILURE) { return; } @@ -2119,9 +2118,7 @@ num_in = zend_hash_num_elements(Z_ARRVAL_P(input)); /* We want all entries from offset to the end if length is not passed or is null */ - if (ZEND_NUM_ARGS() = 3 Z_TYPE_P(length_param) != IS_NULL) { - length = Z_LVAL_P(length_param); - } else { + if (length == IS_NULL) { length = num_in; } -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
if (ZEND_NUM_ARGS() = 3 Z_TYPE_P(length_param) != IS_NULL) { +convert_to_long(length_param); Isn't convert_to_long non-separating one? I think the variable supposed to be separated before conversion, so convert_to_long_ex (and zval **) would be in place. Hm you're probably right... if (ZEND_NUM_ARGS() = 3 Z_TYPE_P(length_param) != IS_NULL) { + convert_to_long_ex(length_param); length = Z_LVAL_P(length_param); } else { length = num_in; - because it's a zval * these days. convert_to_long() didn't break it when I checked, though I probably have the length assignment wrong in the one I posted, on reflection. (Too many patches floating around here at present, sorry.) +if (length == IS_NULL) { Did you really mean IS_NULL here? It builds without complaint and works as expected - what am I missing? - Steph -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
It builds without complaint and works as expected - what am I missing? IS_NULL is variable type. length is variable value. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
So it's better to check for == 0? What's the difference? Is an IS_NULL check slower? No, it's not slower, but it makes no sense to compare variable value to a type constant. Even if coincidentally constant value is the same one you need to compare to. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
It builds without complaint and works as expected - what am I missing? IS_NULL is variable type. length is variable value. So it's better to check for == 0? What's the difference? Is an IS_NULL check slower? - Steph -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
Both are now on http://bugs.php.net/bug.php?id=43541. Ignore the first of the three, it breaks when the length param isn't passed. I'm going offline before I say anything else stupid :) - Steph - Original Message - From: Steph Fox [EMAIL PROTECTED] To: Stanislav Malyshev [EMAIL PROTECTED] Cc: internals@lists.php.net Sent: Monday, December 10, 2007 8:12 PM Subject: Re: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice) So it's better to check for == 0? What's the difference? Is an IS_NULL check slower? No, it's not slower, but it makes no sense to compare variable value to a type constant. Even if coincidentally constant value is the same one you need to compare to. OK, so if I clean up those patches and re-send, will one of them be applied? (It'd be nice to have some idea which one...) - Steph -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
Hi Stas, I just spent most of two evenings looking at this one - so much for an easy fix. Read on... the code is if (ZEND_NUM_ARGS() = 3 Z_TYPE_P(length_param) != IS_NULL) { length = Z_LVAL_P(length_param); } else { length = num_in; } and afaik should be I think in fact it should just parse it as long and not as zval - what would be any reason to parse it as zval and then convert to long anyway? The problem is that this function's always been wrong, so it doesn't really care what you throw at it - it just does a silent conversion to long if you get it wrong. If you turn the parameter into a long now, there's a good chance of breaking a lot of code out there - not least because at present if you give array_slice() a length of 0, that's what it (sanely or otherwise) takes it to mean. If you fix it, it will see 0 as meaning 'everything to the end of the array'. So one of the tests at present is: var_dump(array_slice($sub_array, 0, 0)); and the expectation is for that to always return: array(0) { } Unfortunately this is far from new behaviour. As far as the original float issue goes: What's been happening up to now is that anything fed in as the third argument gets converted to a long, and now it doesn't. Should be easy enough to sort out you'd think, but when you try to do: /* We want all entries from offset to the end if length is not passed or is null */ if (ZEND_NUM_ARGS() = 3 Z_TYPE_P(length_param) != IS_NULL) { convert_to_long_ex(length_param); length = Z_LVAL_P(length_param); } else { length = num_in; } all of a sudden the fourth parameter, preserve_keys, doesn't throw zend_parse_parameter() warnings any more, regardless of the type you give it. (You tell me...) There's also the issue of what to do about inappropriate vs appropriate input types, since we can't rely on zend_parse_parameters() to psychically know that this particular zval is really a loose long kind of thing... so I tried: if (ZEND_NUM_ARGS() = 3 Z_TYPE_P(length_param) IS_DOUBLE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, integer expected in parameter 3, %s given, zend_zval_type_name(length_param)); } This actually doesn't seem to harm anything, but I bet Dmitry'd say otherwise (it probably slows the function right down). So - not as straightforward as it looks, whatever way you look at it. Maybe we should just revert to the old, messy but mostly working code for array_slice()? - Steph -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
all of a sudden the fourth parameter, preserve_keys, doesn't throw zend_parse_parameter() warnings any more, regardless of the type you give it. (You tell me...) ... because I re-used the same variable in the test script after it had been converted to long. OK, so that mystery's solved. But the rest still stands. - Steph -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
I think in fact it should just parse it as long and not as zval - what would be any reason to parse it as zval and then convert to long anyway? The problem is that this function's always been wrong, so it doesn't really care what you throw at it - it just does a silent conversion to long if you get it wrong. If you turn the parameter into a long now, Right, that's what l parameter spec is doing, doesn't it? Why convert it manually? There's also the issue of what to do about inappropriate vs appropriate input types, since we can't rely on zend_parse_parameters() to psychically know that this particular zval is really a loose long kind of thing... so I tried: What's loose long? So - not as straightforward as it looks, whatever way you look at it. Maybe we should just revert to the old, messy but mostly working code for array_slice()? I still don't understand what prevents one from using new parameter parsing API and why manual conversions doing the same are needed. -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
Right, that's what l parameter spec is doing, doesn't it? Why convert it manually? Because it doesn't know the difference between NULL and 0 if it's a long. And why this difference is important in array_slice()? I don't see anything in manual that says anything about NULLs. Could you explain? One that doesn't break every script that didn't strictly stay with int over the last 8 years or so. Errm... I still don't understand. Could you give code example? -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
Hi, i have tried a current snapshot of PHP 5.3 and have a question regarding type hinting. For example when using the function array_slice(array $array, int $offset, int $length) with a non-integer length parameter, what is the desired behavior? When calling array_slice($array, 0, (float)2); the resulting array is EMPTY. When using the right type array_slice($array, 0, (int)2); it works as expected. Shouldn't there be a notice/warning than just a wrong return value? In my case there is neither a warning nor does it work as expected. (perhaps i do something wrong?) Of course i can use int's, but in my opinion either a warning should be given or the function should gracefully handle the wrong typed parameter. Is this problem specific to array_splice or the same with other functions? It works with 5.2.x without a problem. Thank you for any feedback, Dirk PS: i posted this to php-general before and someone supposed to better post it to the iternals list -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
RE: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
Hi Dirk, When calling array_slice($array, 0, (float)2); the resulting array is EMPTY. When using the right type array_slice($array, 0, (int)2); it works as expected. i think this should print a warning like other array functions. But i looked into the src and this looks more like a casting bug inside this function. $input = array('a', 'b', 'c', 'd', 'e'); var_dump(array_slice($input, 1, 1)); var_dump(array_slice($input, 1, 1)); var_dump(array_slice($input, 1, (FLOAT)1)); var_dump(array_slice($input, 1, 1.0)); output: array(1) { [0]= string(1) b } array(1) { [0]= string(1) b } array(0) { } array(0) { } So i think the float value isnt correct casted as int value here. Maybe someone else can proof this. -- Marco -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
Hi, When calling array_slice($array, 0, (float)2); the resulting array is EMPTY. When using the right type array_slice($array, 0, (int)2); it works as expected. i think this should print a warning like other array functions. But i looked into the src and this looks more like a casting bug inside this function. Actually most functions use implicit type conversions for this. So I wouldn't say this should cause a warning. So i think the float value isnt correct casted as int value here. Maybe someone else can proof this. Yes, you are right here I think the code is if (ZEND_NUM_ARGS() = 3 Z_TYPE_P(length_param) != IS_NULL) { length = Z_LVAL_P(length_param); } else { length = num_in; } and afaik should be if (ZEND_NUM_ARGS() = 3 Z_TYPE_P(length_param) != IS_NULL) { convert_to_long(length_param); length = Z_LVAL_P(length_param); } else { length = num_in; } best regards Moritz Bechler -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)
the code is if (ZEND_NUM_ARGS() = 3 Z_TYPE_P(length_param) != IS_NULL) { length = Z_LVAL_P(length_param); } else { length = num_in; } and afaik should be I think in fact it should just parse it as long and not as zval - what would be any reason to parse it as zval and then convert to long anyway? -- Stanislav Malyshev, Zend Software Architect [EMAIL PROTECTED] http://www.zend.com/ (408)253-8829 MSN: [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php