Fw: [PHP-DEV] question regarding type hinting parameters of php functions (array_slice)

2007-12-10 Thread Steph Fox
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)

2007-12-10 Thread Stanislav Malyshev

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)

2007-12-10 Thread Steph Fox
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)

2007-12-10 Thread Steph Fox

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)

2007-12-10 Thread Stanislav Malyshev

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)

2007-12-10 Thread Stanislav Malyshev
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)

2007-12-10 Thread Steph Fox

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)

2007-12-10 Thread Steph Fox

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)

2007-12-09 Thread Steph Fox

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)

2007-12-09 Thread Steph Fox
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)

2007-12-09 Thread Stanislav Malyshev
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)

2007-12-09 Thread Stanislav Malyshev
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)

2007-11-28 Thread Dirk Thomas / 4wd media

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)

2007-11-28 Thread Marco Kaiser
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)

2007-11-28 Thread Moritz Bechler
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)

2007-11-28 Thread Stanislav Malyshev

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