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