Hi!
I notice that 5.3 differs from 5.2 in how array_key_exists treats
objects. In 5.2, if the second parameter (array) is allowed to be object
and HASH_OF is applied to it. However, in 5.3 it would produce a warning
requiring an array if object passed to it. Was it intentional?
Maybe the problem is deeper and is in zend_parse_arg_impl where it
should allow objects for 'a' if we can have HASH_OF from them?
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Stanislav Malyshev wrote:
Hi!
I notice that 5.3 differs from 5.2 in how array_key_exists treats
objects. In 5.2, if the second parameter (array) is allowed to be object
and HASH_OF is applied to it. However, in 5.3 it would produce a warning
requiring an array if object passed to it. Was it intentional?
Maybe the problem is deeper and is in zend_parse_arg_impl where it
should allow objects for 'a' if we can have HASH_OF from them?
To my understanding, it's superseded by the function property_exists.
Also notice the difference of argument order.
As written here: http://docs.php.net/array_key_exists
Hi!
I notice that 5.3 differs from 5.2 in how array_key_exists treats
objects. In 5.2, if the second parameter (array) is allowed to be object
and HASH_OF is applied to it. However, in 5.3 it would produce a warning
requiring an array if object passed to it. Was it intentional?
Maybe the problem is deeper and is in zend_parse_arg_impl where it
should allow objects for 'a' if we can have HASH_OF from them?To my understanding, it's superseded by the function property_exists.
Also notice the difference of argument order.
Ah, ok, missed this note, thanks.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi Stas,
2008/10/23 Stanislav Malyshev stas@zend.com:
Hi!
I notice that 5.3 differs from 5.2 in how array_key_exists treats
objects. In 5.2, if the second parameter (array) is allowed to be object
and HASH_OF is applied to it. However, in 5.3 it would produce a warning
requiring an array if object passed to it. Was it intentional?
Maybe the problem is deeper and is in zend_parse_arg_impl where it
should allow objects for 'a' if we can have HASH_OF from them?To my understanding, it's superseded by the function property_exists.
Also notice the difference of argument order.Ah, ok, missed this note, thanks.
In fact, all HASH_OF was removed in standard/array.c, and that's
already is mentioned implicitly though, as
"The functions next()
/current/… don't take objects anymore as
parameters. For accessing their properties using this way you have to
cast the objects to arrays first."
--
Regards,
Felipe Pena.
But wouldn't be useful to at least accept objects implementing ArrayAccess?
Stanislav Malyshev wrote:
Hi!
I notice that 5.3 differs from 5.2 in how array_key_exists treats
objects. In 5.2, if the second parameter (array) is allowed to be object
and HASH_OF is applied to it. However, in 5.3 it would produce a warning
requiring an array if object passed to it. Was it intentional?
Maybe the problem is deeper and is in zend_parse_arg_impl where it
should allow objects for 'a' if we can have HASH_OF from them?To my understanding, it's superseded by the function property_exists.
Also notice the difference of argument order.As written here: http://docs.php.net/array_key_exists
On Fri, Oct 24, 2008 at 1:05 PM, Ionut Gabriel Stan
ionut.g.stan@gmail.com wrote:
But wouldn't be useful to at least accept objects implementing ArrayAccess?
sounds like a good idea to me
Stanislav Malyshev wrote:
Hi!
I notice that 5.3 differs from 5.2 in how array_key_exists treats
objects. In 5.2, if the second parameter (array) is allowed to be object
and HASH_OF is applied to it. However, in 5.3 it would produce a warning
requiring an array if object passed to it. Was it intentional?
Maybe the problem is deeper and is in zend_parse_arg_impl where it
should allow objects for 'a' if we can have HASH_OF from them?To my understanding, it's superseded by the function property_exists.
Also notice the difference of argument order.As written here: http://docs.php.net/array_key_exists
--
--
Alexey Zakhlestin
http://blog.milkfarmsoft.com/
On Fri, Oct 24, 2008 at 1:05 PM, Ionut Gabriel Stan
ionut.g.stan@gmail.com wrote:But wouldn't be useful to at least accept objects implementing ArrayAccess?
sounds like a good idea to me
nope that would mean that some scripts might work different between 5.2
and 5.3, now one gets an error. consider such a script:
<?php
class Foo extends ArrayAccess {
public $prop = 42;
function offsetGet($n) { ... }
....
}
$o = new foo;
array_key_Exists('prop', $o);
?>
In <= 5.2 it will return the value of $o->prop, in 5.3 it would call the
offsetGet() method.
I prefer an error, if many people want the old behavior that's fine to
me, but don't change it.
btw. this also affects quite a few other functions: next/current/key/...
at least ... and maybe more after using the "new" parameter parsing API.
johannes
Hi!
nope that would mean that some scripts might work different between 5.2
and 5.3, now one gets an error. consider such a script:
Just so it is clear - some scripts ALREADY work differently, that's why
it says "BC break".
<?php
class Foo extends ArrayAccess {
public $prop = 42;
function offsetGet($n) { ... }
....
}$o = new foo;
array_key_Exists('prop', $o);
?>In <= 5.2 it will return the value of $o->prop, in 5.3 it would call the
offsetGet() method.
In 5.2 it would return true and not the value of $o->prop.
In 5.3 I don't think it would call offsetGet. It would call
get_properties method of ArrayAccess, and that should return list of
object's properties as array, so in this case the return will still be true.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi!
nope that would mean that some scripts might work different between 5.2
and 5.3, now one gets an error. consider such a script:Just so it is clear - some scripts ALREADY work differently, that's why
it says "BC break".
There's a difference between "working differently, but doing something"
and "throwing an error".
<?php
class Foo extends ArrayAccess {
public $prop = 42;
function offsetGet($n) { ... }
....
}$o = new foo;
array_key_Exists('prop', $o);
?>In <= 5.2 it will return the value of $o->prop, in 5.3 it would call the
offsetGet() method.In 5.2 it would return true and not the value of $o->prop.
In 5.3 I don't think it would call offsetGet. It would call
get_properties method of ArrayAccess, and that should return list of
object's properties as array, so in this case the return will still be true.
I didn't check array_key_exists but most of the affected functions use
Z_OBJ_HT and therefore directly access the property table, not the
property access APIs.
Now changing to these APIs will be a silent change, whereas the old
behavior might be considered as a bug, throwing an error might be a good
compromise.
Example showing the 3 different behaviors:
$ cat array_key_exists_array_access.php
<?php
class Test implements ArrayAccess {
public $prop = "property";
public function offsetExists($key) {
echo __METHOD__,"($key)\n";
return false;
}
public function offsetGet($key) {
echo __METHOD__,"($key)\n";
return null;
}
public function offsetSet($key, $value) {}
public function offsetUnset($key) {}
}
$o = new Test();
var_dump(array_key_exists("prop", $o));
?>
$ php52 array_key_exists_array_access.php
bool(true)
$ php53 array_key_exists_array_access.php
Warning: array_key_exists()
expects parameter 2 to be array, object
given in /home/johannes/public_html/- on line 20
NULL
Result after using ArrayAccess:
Test::offsetExistst(prop)
bool(false)
Going from 1) to 3) will certainly confuse users and leads to changes in
behavior which can't be found in an easy way...
johannes
Johannes Schlüter wrote:
btw. this also affects quite a few other functions: next/current/key/...
at least ... and maybe more after using the "new" parameter parsing API.
I would say "no" for 5.3. But for 6 it would be fantastic to have all array-related
operations supporting ArrayAccess interface, where possible.
-Andrei
btw. this also affects quite a few other functions: next/current/
key/...
at least ... and maybe more after using the "new" parameter parsing
API.I would say "no" for 5.3. But for 6 it would be fantastic to have
all array-related operations supporting ArrayAccess interface, where
possible.
I was hoping someone would revive this thread (-:
In Habari, we have/had an ArrayObject that we passed to the view
(theme). As far as the theme knows, this is an array (but it has extra
methods if the theme is particularly smart).
Unfortunately, this breaks in 5.3, because many of the themes use
reset()
to get the first element of the array (ArrayObject, but the
theme doesn't necessarily know this).
This is a real-world BC break, and without allowing ArrayObject to act
like an array, it's nearly useless. We've temporarily "solved" this by
casting the ArrayObject to an array, which is silly. This should be
fixed in 5.3, IMO.
I discussed this with Johannes a bit, yesterday.
S
Sean Coates wrote:
I was hoping someone would revive this thread (-:
In Habari, we have/had an ArrayObject that we passed to the view
(theme). As far as the theme knows, this is an array (but it has extra
methods if the theme is particularly smart).Unfortunately, this breaks in 5.3, because many of the themes use
reset()
to get the first element of the array (ArrayObject, but the
theme doesn't necessarily know this).This is a real-world BC break, and without allowing ArrayObject to act
like an array, it's nearly useless. We've temporarily "solved" this by
casting the ArrayObject to an array, which is silly. This should be
fixed in 5.3, IMO.I discussed this with Johannes a bit, yesterday.
I see. If it's a real-world BC break, then it should be fixed.
-a
Hi Andrei,
Am Montag, den 27.10.2008, 11:34 -0700 schrieb Andrei Zmievski:
[...]
I would say "no" for 5.3. But for 6 it would be fantastic to have all array-related
operations supporting ArrayAccess interface, where possible.
+1 for this.
cu, Lars
Jabber: lars@strojny.net
Weblog: http://usrportage.de
While we're at this and considering the new lambdas that we now have in
the language
I must say I'd like some functions to support Traversables. Those would be:
array_map()
, array_reduce()
, array_filter()
, array_walk()
and
array_walk_recursive()
Although I'd rather want a class (because the array_* functions don't
adhere to some strict param order standards)
to provide functional style methods, like those in Javascript 1.8:
https://developer.mozilla.org/index.php?title=En/New_in_JavaScript_1.6#section_2
https://developer.mozilla.org/index.php?title=En/New_in_JavaScript_1.8#section_4
Array.forEach()
Array.map()
Array.filter()
Array.reduce()
Array.reduceRight()
Array.some()
Array.every()
In PHP something like this would be nice:
$processedDirectoryIterator = SplFunctional(new
DirecotoryIterator(DIR)).map(function() {
// do stuff here
});
where SplFunctional is a function returning a SplFunctional object whose
construcor accepts iteratable
structures (arrays or Traversables) and $processDirectoryIterator is a
DirectoryIterator resulted after applying
the lamba to each of the SplFileObjects contained.
I know right now we have FilterIterator as an equivalent to
array_filter()
for Iterators and we could implement our
own Functional classes but that means a new class for situations where a
simple lambda could do the job
just as well.
I hope my proposal makes sense.
P.S. I introduced a SplFunctional function just to skip the
instantiation of the object.
Hi Andrei,
Am Montag, den 27.10.2008, 11:34 -0700 schrieb Andrei Zmievski:
[...]I would say "no" for 5.3. But for 6 it would be fantastic to have all array-related
operations supporting ArrayAccess interface, where possible.+1 for this.
cu, Lars
Hi Ionut,
Am Dienstag, den 28.10.2008, 16:00 +0200 schrieb Ionut Gabriel Stan:
[...]
While we're at this and considering the new lambdas that we now have
in the language I must say I'd like some functions to support
Traversables.
Nevertheless I agree that this would be a great feature, I would like to
ask to stop concrete feature evaluation here and write an RFC so we have
something to read before we start to think about "what would be nice?".
cu, Lars
Jabber: lars@strojny.net
Weblog: http://usrportage.de
Hi Ionut
2008/10/28 Ionut Gabriel Stan ionut.g.stan@gmail.com:
While we're at this and considering the new lambdas that we now have in the
language
I must say I'd like some functions to support Traversables. Those would be:
array_map()
,array_reduce()
,array_filter()
,array_walk()
and
array_walk_recursive()
Although I'd rather want a class (because the array_* functions don't adhere
to some strict param order standards)
to provide functional style methods, like those in Javascript 1.8:https://developer.mozilla.org/index.php?title=En/New_in_JavaScript_1.6#section_2
https://developer.mozilla.org/index.php?title=En/New_in_JavaScript_1.8#section_4Array.forEach()
Array.map()
Array.filter()
Array.reduce()
Array.reduceRight()
Array.some()
Array.every()In PHP something like this would be nice:
$processedDirectoryIterator = SplFunctional(new
DirecotoryIterator(DIR)).map(function() {
// do stuff here
});
This would indeed be nice, but theres one thing yet, PHP doesn't
support closure objects, take for example:
<?php
class Test
{
public function hello($who)
{
echo 'Hello ' . $who;
}
}
$closure = function()
{
static $instance;
if(!$instance)
{
$instance = new Test;
}
return($instance);
};
$closure->hello('Kalle'); // Fatal error, undefined method Closure::hello()
But you should indeed make an RFC for this and even create a patch if
you're able to :)
where SplFunctional is a function returning a SplFunctional object whose
construcor accepts iteratable
structures (arrays or Traversables) and $processDirectoryIterator is a
DirectoryIterator resulted after applying
the lamba to each of the SplFileObjects contained.I know right now we have FilterIterator as an equivalent to
array_filter()
for Iterators and we could implement our
own Functional classes but that means a new class for situations where a
simple lambda could do the job
just as well.I hope my proposal makes sense.
P.S. I introduced a SplFunctional function just to skip the instantiation of
the object.Hi Andrei,
Am Montag, den 27.10.2008, 11:34 -0700 schrieb Andrei Zmievski:
[...]I would say "no" for 5.3. But for 6 it would be fantastic to have all
array-related
operations supporting ArrayAccess interface, where possible.+1 for this.
cu, Lars
--
--
Kalle Sommer Nielsen
Hi,
Thanks for your positive feedback about my idea and sorry for hijacking this
thread.
Although my C skills are limited to its syntax only I'll create an RFC, then
someone
else might give it a try an create a patch.
All the best,
Ionut
On Tue, Oct 28, 2008 at 4:23 PM, Kalle Sommer Nielsen
kalle.php@gmail.comwrote:
Hi Ionut
2008/10/28 Ionut Gabriel Stan ionut.g.stan@gmail.com:
While we're at this and considering the new lambdas that we now have in
the
language
I must say I'd like some functions to support Traversables. Those would
be:
array_map()
,array_reduce()
,array_filter()
,array_walk()
and
array_walk_recursive()
Although I'd rather want a class (because the array_* functions don't
adhere
to some strict param order standards)
to provide functional style methods, like those in Javascript 1.8:https://developer.mozilla.org/index.php?title=En/New_in_JavaScript_1.6#section_2
https://developer.mozilla.org/index.php?title=En/New_in_JavaScript_1.8#section_4
Array.forEach()
Array.map()
Array.filter()
Array.reduce()
Array.reduceRight()
Array.some()
Array.every()In PHP something like this would be nice:
$processedDirectoryIterator = SplFunctional(new
DirecotoryIterator(DIR)).map(function() {
// do stuff here
});This would indeed be nice, but theres one thing yet, PHP doesn't
support closure objects, take for example:<?php
class Test
{
public function hello($who)
{
echo 'Hello ' . $who;
}
}$closure = function()
{
static $instance;if(!$instance) { $instance = new Test; } return($instance);
};
$closure->hello('Kalle'); // Fatal error, undefined method Closure::hello()
But you should indeed make an RFC for this and even create a patch if
you're able to :)where SplFunctional is a function returning a SplFunctional object whose
construcor accepts iteratable
structures (arrays or Traversables) and $processDirectoryIterator is a
DirectoryIterator resulted after applying
the lamba to each of the SplFileObjects contained.I know right now we have FilterIterator as an equivalent to
array_filter()
for Iterators and we could implement our
own Functional classes but that means a new class for situations where a
simple lambda could do the job
just as well.I hope my proposal makes sense.
P.S. I introduced a SplFunctional function just to skip the instantiation
of
the object.Hi Andrei,
Am Montag, den 27.10.2008, 11:34 -0700 schrieb Andrei Zmievski:
[...]I would say "no" for 5.3. But for 6 it would be fantastic to have all
array-related
operations supporting ArrayAccess interface, where possible.+1 for this.
cu, Lars
--
--
Kalle Sommer Nielsen
I would say "no" for 5.3. But for 6 it would be fantastic to have all
array-related
operations supporting ArrayAccess interface, where possible.+1 for this.
Hi,
cu, Lars
Just making sure but: I think the BC break should be fixed. It's breaking
actual code out there. The practice of passing traversable objects to our
views, mixed with real arrays, is already common (I do it too).
Regards,
Stan Vassilev
I would say "no" for 5.3. But for 6 it would be fantastic to have
all array-related
operations supporting ArrayAccess interface, where possible.+1 for this.
Hi,
cu, LarsJust making sure but: I think the BC break should be fixed. It's
breaking actual code out there. The practice of passing traversable
objects to our views, mixed with real arrays, is already common (I
do it too).
so where do we stand here?
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Hi!
so where do we stand here?
I'd prefer to have it fixed, but then it probably requires changing the
parameters API for 'a', which might lead to some unexpected results with
regard to functions that modify their arguments. I think we may leave it
alone for this alpha but try to resolve it for 5.3 release.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
I'd prefer to have it fixed, but then it probably requires changing
the parameters API for 'a', which might lead to some unexpected
results with regard to functions that modify their arguments. I
think we may leave it alone for this alpha but try to resolve it for
5.3 release.
If my opinion matters, I'd also prefer to see that fixed. As I
mentioned earlier in the thread, ArrayObject loses a lot of value if
it can't be treated as an array.
S
so where do we stand here?
I'd prefer to have it fixed, but then it probably requires changing
the parameters API for 'a', which might lead to some unexpected
results with regard to functions that modify their arguments. I
think we may leave it alone for this alpha but try to resolve it for
5.3 release.
If it isn't fixed it ought to be a documented as a BC break, seeming
it does break real apps.
--
Geoffrey Sneddon
<http://gsnedders.com/
Hi all,
Em Qua, 2008-11-05 às 16:20 +0000, Geoffrey Sneddon escreveu:
so where do we stand here?
I'd prefer to have it fixed, but then it probably requires changing
the parameters API for 'a', which might lead to some unexpected
results with regard to functions that modify their arguments. I
think we may leave it alone for this alpha but try to resolve it for
5.3 release.If it isn't fixed it ought to be a documented as a BC break, seeming
it does break real apps.
So as suggested and wished, here is a patch that add a modifier '%' to
'a' in parameter parsing API, where it allows object that implements
ArrayAccess to be accept. Although it doesn't invoke any their methods,
i.e. just how it works nowdays.
A list of functions that allow object on current 5.2:
. end
. prev
. next
. reset
. current
. key
. array_key_exists
. array_unique
. array_flip
. array_walk_recursive
. array_walk
. uksort
. uasort
. usort
. natcasesort
. natsort
Hence, I added such modifier to this functions in the patch.
5.3: http://felipe.ath.cx/diff/arg_arrayaccess.diff
--
Regards,
Felipe Pena
So as suggested and wished, here is a patch that add a modifier '%' to
'a' in parameter parsing API, where it allows object that implements
ArrayAccess to be accept. Although it doesn't invoke any their
methods,
i.e. just how it works nowdays.
I applied this to HEAD and ran a few minor (manual) tests on
ArrayObject, and it worked as expected (as it does in 5.2). Thanks!
S
I applied this to HEAD
Oops. I mean to PHP_5_3 (keep forgetting that it's not HEAD).
S
Hi!
So as suggested and wished, here is a patch that add a modifier '%' to
'a' in parameter parsing API, where it allows object that implements
ArrayAccess to be accept. Although it doesn't invoke any their methods,
i.e. just how it works nowdays.
I think if you use HASH_OF then any object having get_properties should
be fine... Is there any reason to restrict it to ArrayAccess?
A list of functions that allow object on current 5.2:
. uksort
. uasort
. usort
. natcasesort
. natsort
Interestingly, this list includes no sort()
. Is it intentional? Also, we
have a bunch of array functions - wouldn't it make sense that all of
them behaved the same way towards objects?
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Em Qui, 2008-11-06 às 10:10 -0800, Stanislav Malyshev escreveu:
Hi!
So as suggested and wished, here is a patch that add a modifier '%' to
'a' in parameter parsing API, where it allows object that implements
ArrayAccess to be accept. Although it doesn't invoke any their methods,
i.e. just how it works nowdays.I think if you use HASH_OF then any object having get_properties should
be fine... Is there any reason to restrict it to ArrayAccess?
Well, there is no reason, I was only following what was said.
It would make more sense in case of real BC break avoiding.
A list of functions that allow object on current 5.2:
. uksort
. uasort
. usort
. natcasesort
. natsortInterestingly, this list includes no
sort()
. Is it intentional? Also, we
have a bunch of array functions - wouldn't it make sense that all of
them behaved the same way towards objects?
Yep, this was really interesting, see:
$x = new stdclass;
$x->foo = 1;
sort($x);
Warning: sort()
expects parameter 1 to be array, object given ...
As other functions that I guess you must be remembered. :)
And yes, I have checked each array function.
--
Regards,
Felipe Pena
Hi!
So as suggested and wished, here is a patch that add a modifier '%' to
'a' in parameter parsing API, where it allows object that implements
ArrayAccess to be accept. Although it doesn't invoke any their methods,
i.e. just how it works nowdays.I think if you use HASH_OF then any object having get_properties should
be fine... Is there any reason to restrict it to ArrayAccess?
This can be wrong/strange with classes implementing ArrayAccess (not
ArrayObject) or Iterator.
An example where one might expect an Iterator, reset()
and next()
use
HASH_OF in 5.2:
<?php
class I implements Iterator {
public $foo = "some real property";
public function `rewind()` {
echo __METHOD__, "\n";
}
public function `current()` {
echo __METHOD__, "\n";
return "from iterator";
}
public function valid() {
static $continue = true;
echo __METHOD__, "\n";
if ($continue) {
$continue = false;
return true;
} else {
return false;
}
}
public function `next()` {} public function `key()` {}
}
$i = new I;
reset($i);
echo current($i);
?>
some real property
And another example using ArrayAccess: array_key_exists uses HASH_OF in
5.2:
<?php
class A implements ArrayAccess {
public $foo = 42;
function offsetExists($k) {
echo METHOD; return false;
}
function offsetGet($k) {}
function offsetSet($k, $v) {}
function offsetUnset($k) {}
}
var_dump(array_key_exists("foo", new A()));
?>
bool(true)
So allowing passing objects to array stuff using HASH_OF can lead to
unexpected behavior. Dropping the old behavior makes this clear ... but
is bad for stuff like ArrayObject.
I'm not sure whether we should add special rules for a single class
though ..
johannes
So allowing passing objects to array stuff using HASH_OF can lead to
unexpected behavior. Dropping the old behavior makes this clear ... but
is bad for stuff like ArrayObject.I'm not sure whether we should add special rules for a single class
though ..johannes
The exception should be made for any class implementing the relevant SPL
interfaces, and that's not just ArrayObject.
It may be seen as just "one class" but actually all of the "transparent"
iterator implementations (for iterating SQL, XML, or whatever data you have)
hinge on those interfaces and that class to work as a normal array with the
array functions.
Regards, Stan Vassilev
The exception should be made for any class implementing the relevant SPL
interfaces, and that's not just ArrayObject.It may be seen as just "one class" but actually all of the "transparent"
iterator implementations (for iterating SQL, XML, or whatever data you have)
hinge on those interfaces and that class to work as a normal array with the
array functions.
a) I showed the 5.2 behavior, using "proper" interfaces is a silent
change which might break application and is probably hard to find. While
I don't know how many people rely on these "features".
b) It can be quite confusing with all of the tons of array functions
accepting different kinds of objects.
johannes
Hi!
a) I showed the 5.2 behavior, using "proper" interfaces is a silent
change which might break application and is probably hard to find. While
I don't know how many people rely on these "features".
I think it'd be OK for functions using HASH_OF in 5.2 keep using that,
and I'm not sure we should ask for any specific interface there.
As for other ones, we need to see if it would make sense there
(something like array_shift probably wouldn't make too much sense on
generic object and won't work correctly with most Array* objects either).
--
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi!
So as suggested and wished, here is a patch that add a modifier '%' to
'a' in parameter parsing API, where it allows object that implements
ArrayAccess to be accept. Although it doesn't invoke any their methods,
i.e. just how it works nowdays.I think if you use HASH_OF then any object having get_properties should
be fine... Is there any reason to restrict it to ArrayAccess?This can be wrong/strange with classes implementing ArrayAccess (not
ArrayObject) or Iterator.An example where one might expect an Iterator,
reset()
andnext()
use
HASH_OF in 5.2:<?php
class I implements Iterator {
public $foo = "some real property";public function
rewind()
{
echo METHOD, "\n";
}
public functioncurrent()
{
echo METHOD, "\n";
return "from iterator";
}
public function valid() {
static $continue = true;echo __METHOD__, "\n"; if ($continue) { $continue = false; return true; } else { return false; }
}
public functionnext()
{} public functionkey()
{}
}$i = new I;
reset($i);
echo current($i);
?>
some real property
Whaaatheef...
I was going to reply back with the actual correct output when I
started wondering how exactly you got these results..
This is a total wtf and just cannot be the intended designed behaviour.
Switching it however "out-of-the-blue" and introducing the weirdest
and really hard-to-debug behaviour is pretty bad.
How many applications do rely on such behaviour though? The manual
clearly says these functions take arrays, not objects, so I can't
believe many do.
At most some legacy PHP4 applications which will never be upgraded to
PHP5 boxes would be my guess.
-Hannes
Hi,
Can anyone write up a summary of the situation and the options we have?
Also cant we some how automate the BC break testing for this (aka scan
all functions that accept an array with the old API in 5.2, pass it an
ArrayObject instance and see what happens and compare that to 5.3)?
regards,
Lukas
Hi!
Can anyone write up a summary of the situation and the options we have?
Sure. A number of array functions in 5.2 accept arrays, but use HASH_OF
to extract array value, which means they automatically accept objects if
the object has working get_properties handler. In 5.3, such function use
new API with 'a' parameter, which accepts only arrays proper.
The proposal is to have some new parameter - say 'a%' - which would call
HASH_OF on objects where it makes sense. The definition of "makes sense"
is not clear yet, since, for example, sort()
on some objects may make
sense - if the object's get_properties returns real storage - or may
not, if that handler returns the mere copy of the real data. We might
use some interface as a marker - like ArrayAccess - though I'm not sure
if it will work in all circumstances.
Also cant we some how automate the BC break testing for this (aka scan
all functions that accept an array with the old API in 5.2, pass it an
ArrayObject instance and see what happens and compare that to 5.3)?
Yes we can ;) That should be not hard to do by looking at ones having
'a' in parameters in 5.3 and comparing how they react to arrays in 5.2
and in 5.3. Some of them, btw, might accept objects even though it
doesn't make much sense - as above.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Also cant we some how automate the BC break testing for this (aka
scan all functions that accept an array with the old API in 5.2,
pass it an ArrayObject instance and see what happens and compare
that to 5.3)?Yes we can ;) That should be not hard to do by looking at ones
having 'a' in parameters in 5.3 and comparing how they react to
arrays in 5.2 and in 5.3. Some of them, btw, might accept objects
even though it doesn't make much sense - as above.
This isn't the type of thing that I would naturally expect to find
broken in a .x release, so if we can preserve the old behaviour with
little to no penalty, I suggest we go for that.
S
Hi!
This isn't the type of thing that I would naturally expect to find
broken in a .x release, so if we can preserve the old behaviour with
little to no penalty, I suggest we go for that.
I'm not sure we can while preserving new API - since old API gave much
more wiggle room to particular function - you get zval** and do whatever
you want. We could convert them to use 'z' and then parse it into arrays
but I think that would be cheating.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi!
Can anyone write up a summary of the situation and the options we
have?Sure. A number of array functions in 5.2 accept arrays, but use
HASH_OF to extract array value, which means they automatically
accept objects if the object has working get_properties handler. In
5.3, such function use new API with 'a' parameter, which accepts
only arrays proper.
The proposal is to have some new parameter - say 'a%' - which would
call HASH_OF on objects where it makes sense. The definition of
"makes sense" is not clear yet, since, for example,sort()
on some
objects may make sense - if the object's get_properties returns real
storage - or may not, if that handler returns the mere copy of the
real data. We might use some interface as a marker - like
ArrayAccess - though I'm not sure if it will work in all
circumstances.
So what if we for now stick with the BC fix?
However maybe for PHP 6.0 we should make a real effort to figure out
how objects are supposed to be handled in our PHP type juggeling world.
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
2008/11/15 Lukas Kahwe Smith mls@pooteeweet.org:
Hi!
Can anyone write up a summary of the situation and the options we have?
Sure. A number of array functions in 5.2 accept arrays, but use HASH_OF to
extract array value, which means they automatically accept objects if the
object has working get_properties handler. In 5.3, such function use new API
with 'a' parameter, which accepts only arrays proper.
The proposal is to have some new parameter - say 'a%' - which would call
HASH_OF on objects where it makes sense. The definition of "makes sense" is
not clear yet, since, for example,sort()
on some objects may make sense -
if the object's get_properties returns real storage - or may not, if that
handler returns the mere copy of the real data. We might use some interface
as a marker - like ArrayAccess - though I'm not sure if it will work in all
circumstances.So what if we for now stick with the BC fix?
However maybe for PHP 6.0 we should make a real effort to figure out how
objects are supposed to be handled in our PHP type juggeling world.
I think we should fix it, if theres BC its most likely people will
draw away from using it, especially people writing cross version
applications if they have to "hack" their way to use this feature. I
like Stas' suggestion for changing the parameter parsing api to
support it like that.
--
Kalle Sommer Nielsen
Hi!
So what if we for now stick with the BC fix?
However maybe for PHP 6.0 we should make a real effort to figure out how
objects are supposed to be handled in our PHP type juggeling world.
Depends what you mean by BC fix. If you mean just rolling these
functions back to using zval** and converting manually, I'm not sure
it's the best idea... It'd be better for parameter parsing API to be
able to handle such things.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi!
So what if we for now stick with the BC fix?
However maybe for PHP 6.0 we should make a real effort to figure
out how objects are supposed to be handled in our PHP type
juggeling world.Depends what you mean by BC fix. If you mean just rolling these
functions back to using zval** and converting manually, I'm not sure
it's the best idea... It'd be better for parameter parsing API to be
able to handle such things.
no i meant .. going along with the fix you suggested. and for those
places where you said we its not clear how things should behave, we
should just go by how things behaved in 5.2.
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Felipe Pena wrote:
So as suggested and wished, here is a patch that add a modifier '%' to
'a' in parameter parsing API, where it allows object that implements
ArrayAccess to be accept. Although it doesn't invoke any their methods,
i.e. just how it works nowdays.A list of functions that allow object on current 5.2:
. end
. prev
. next
. reset
. current
. key
. array_key_exists
. array_unique
. array_flip
. array_walk_recursive
. array_walk
. uksort
. uasort
. usort
. natcasesort
. natsortHence, I added such modifier to this functions in the patch.
It should probably be '#', because that modifier means 'alternate representation'.
-Andrei
I meant '&' actually.
-Andrei
2008/11/17 Andrei Zmievski andrei@gravitonic.com:
I meant '&' actually.
-Andrei
Ok, patch updated. http://felipe.ath.cx/diff/array_bc.diff
Go go go?
The rest is to fix 25 (at least ext/standard/array/) tests failing like:
343+ Warning: current()
expects parameter 1 to be array or object,
null given in %s on line %d
343- Warning: current()
expects parameter 1 to be array, null given in
%s on line %d
--
Regards,
Felipe Pena
Hi!
. end
. prev
. next
. reset
. current
. key
I think those should be more friendly with Iterators, but for other
objects probably not much sense to allow it. In 5.2 they modify or use
current hash pointer, but for objects that doesn't make too much sense.
. array_key_exists
Here it may make some sense, though I guess it should maybe go through
more specific handlers (i.e. has_dimension or has_property?). Also,
feels weird that key_exists works but in_array doesn't.
. array_unique
. array_flip
. array_walk_recursive
. array_walk
Those are ok with any object, in theory, though it's not clear why you
could do array_flip on object but not array_reverse or
array_keys/values. Maybe we should not have object support from those,
except array_walk_* for Iterators? If you want something else, get
properties manually...
. uksort
. uasort
. usort
. natcasesort
. natsort
These frankly make little sense with objects and also other sorts do not
support object, so I'd say this is just a bug that they allow objects at
all.
Any comments?
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi!
. end
. prev
. next
. reset
. current
. keyI think those should be more friendly with Iterators, but for other
objects probably not much sense to allow it. In 5.2 they modify or use
current hash pointer, but for objects that doesn't make too much sense.
Using iterators there might make sense, but two things to consider:
-
prev()
doesn't map to Iterator, so we might leave it out - Doing that is a (silent) change in behavior, not going to the
property's hashtable but the iterator interface, not sure if it
hurts anybody, though .. language-wise I guess it makes more sense to
allow iterators
. array_key_exists
Here it may make some sense, though I guess it should maybe go through
more specific handlers (i.e. has_dimension or has_property?). Also,
feels weird that key_exists works but in_array doesn't.. array_unique
. array_flip
. array_walk_recursive
. array_walkThose are ok with any object, in theory, though it's not clear why you
could do array_flip on object but not array_reverse or
array_keys/values. Maybe we should not have object support from those,
except array_walk_* for Iterators? If you want something else, get
properties manually...
I don't think we should pick a single function to do iterator stuff,
especially as there's iterator_apply()
doing the same thing for some
time.
. uksort
. uasort
. usort
. natcasesort
. natsortThese frankly make little sense with objects and also other sorts do not
support object, so I'd say this is just a bug that they allow objects at
all.
I agree.
johannes
Hi,
Hmm, I really think we should simply maintain BC 100% but using the
new parameter parsing API and then really think this through for the
next bigger release (presumably PHP 6.0) and come up with a set of
interfaces for objects that allow them to more sensibly work with
functions.
regards,
Lukas
Hi!
Hmm, I really think we should simply maintain BC 100% but using the new
BC 100% makes little sense - why usort can accept object but sort can't?
And functions like next/prev are useless with many types of objects.
Especialy think this through for the next
bigger release (presumably PHP 6.0) and come up with a set of interfaces
for objects that allow them to more sensibly work with functions.
We already have set of interfaces. They aren't just used consistently.
And that's a bug. We shouldn't let BC to prevent us from fixing bugs.
Especially BC with things that were never documented to work at the
first place and are working in half of functions and don't work in
others without any logical order.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
bigger release (presumably PHP 6.0) and come up with a set of
interfaces for objects that allow them to more sensibly work with
functions.We already have set of interfaces. They aren't just used
consistently. And that's a bug. We shouldn't let BC to prevent us
from fixing bugs. Especially BC with things that were never
documented to work at the first place and are working in half of
functions and don't work in others without any logical order.
I am just worried that we do not have enough time to really think this
through all the way. So in the end we might end up having to break BC
once more in PHP 6.0. Also its not like we are fixing these bugs
because users were submitting bug tickets about this (or have they?).
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Hi!
I am just worried that we do not have enough time to really think this
through all the way. So in the end we might end up having to break BC
once more in PHP 6.0. Also its not like we are fixing these bugs because
users were submitting bug tickets about this (or have they?).
Well, some of it is used - I was bit by array_key_exists, though I'm not
sure it's properly used there anyway. But I think it's low-profile
change, since I have hard time believing somebody relies on natsort
working on objects, especially since other sort don't work and
ArrayObject has its own natsort. I think it's a good chance to clean up.
Maybe iterator things can be delayed, if you think they are high-risk.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi!
Hmm, I really think we should simply maintain BC 100% but using the new
BC 100% makes little sense - why usort can accept object but sort can't?
And functions like next/prev are useless with many types of objects.
Especialy think this through for the nextbigger release (presumably PHP 6.0) and come up with a set of interfaces
for objects that allow them to more sensibly work with functions.We already have set of interfaces. They aren't just used consistently. And
that's a bug. We shouldn't let BC to prevent us from fixing bugs.
Especially BC with things that were never documented to work at the first
place and are working in half of functions and don't work in others
without any logical order.
As a PHP user who'd want to migrate to 5.3 sooner than later, and uses those
heavily, I'd rather not see BC breaks in a point release, even though just
like you I see some WTF-s in the old behaviour.
Full rethinking of this and consistently respecting the Array/Iterator
interfaces would be great and needed for 6.0, though.
Regards, Stan Vassilev
Hi!
As a PHP user who'd want to migrate to 5.3 sooner than later, and uses
those heavily, I'd rather not see BC breaks in a point release, even
though just like you I see some WTF-s in the old behaviour.
You heavily use natsort on objects? What for?
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hi!
As a PHP user who'd want to migrate to 5.3 sooner than later, and uses
those heavily, I'd rather not see BC breaks in a point release, even
though just like you I see some WTF-s in the old behaviour.You heavily use natsort on objects? What for?
If natsort covered the entirety of this BC break, I guess we wouldn't be
having this discussion.
Regards, Stan Vassilev
Hmm, I really think we should simply maintain BC 100% but using the
new parameter parsing API and then really think this through for the
next bigger release (presumably PHP 6.0) and come up with a set of
interfaces for objects that allow them to more sensibly work with
functions.
FWIW, I agree here. Yes, it's "wrong" now, but BC breaks like this in
point releases upset a lot of people and discourage early adoption.
I'd much prefer to see this in 6.0, especially if we can raise
E_DEPRECATED
in the meantime.
S
Hi!
. end
. prev
. next
. reset
. current
. key
. array_key_exists
. array_unique
. array_flip
. array_walk_recursive
. array_walk
. uksort
. uasort
. usort
. natcasesort
. natsort
Attached is the patch that should restore BC for all those functions
except sorts and array_unique/array_flip (these should be trivial too
but I still thing their support for objects is just a bug). Please tell
if you are using those (ones not BCed) in any meaningful scenario on
objects.
This is done by having 'a' and 'h' specifiers have sister ones 'A' and
'H' that would accept objects if those have working HASH_OF. I have
opted out for new letters and not sign since signs currently used for
generic modifiers (like "separate it") and object-array relation is not
generic.
Any comments?
And last but not least - anybody cares to write tests for those
object/array cases?
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Attached is the patch that should restore BC for all those functions
except sorts and array_unique/array_flip (these should be trivial too
but I still thing their support for objects is just a bug). Please tell
if you are using those (ones not BCed) in any meaningful scenario on
objects.This is done by having 'a' and 'h' specifiers have sister ones 'A' and
'H' that would accept objects if those have working HASH_OF. I have
opted out for new letters and not sign since signs currently used for
generic modifiers (like "separate it") and object-array relation is not
generic.
Any comments?
Only one comment: Could you please update README.PARAMETER_PARSING, too?
Thanks!
johannes
Hello,
I have reported this bug http://bugs.php.net/bug.php?id=46354, because
new behaviour breaks my script. The question is how fix scripts for new
behaviour. Example:
// common array
$a = array('item' => NULL);
isset($a['item']) -> FALSE
array_key_exists($a['item']) -> TRUE
// ArrayObject
$o = new ArrayObject($a);
isset($o['item']) -> TRUE
(!)
$o->offsetExists($o['item']) -> TRUE
(!), in PHP 5.2.1 FALSE
(!)
Should one rely on this 'isset' behaviour, i.e. will isset($a['item'])
return TRUE
in future?
David Grudl