On 24/11/11 06:25, Stas Malyshev wrote:
> Hi!
>
>> The only case where the 5.4 branch works differently as before if you
>> reference a string type(int, float, etc. won't trigger this) variable
>> using an associative index and you expect it that to be undefined
>> variable even though that the documentation explicitly states that the
>
> Actually, the only change 5.4 did was to make $a['foo']['bar'] work
> like ($a['foo'])['bar'] - i.e. chained offsets work the same way as if
> they were applied separately. That's it. All the rest has been there
> since forever. I can't see how one could argue it should stay this way.
>
> Now I'm sorry somebody used the fact that chained offsets didn't work
> to do a check "do we have any strings there" but that's not how PHP is
> supposed to work and it's clearly a side-effect of a bug.

One thing that I wasn't aware of was the string to int conversion for
string offsets. IMO, that should trigger a notice or something. Good to
be reminded of though.

Just to clarify, the changes introduced in 5.4 will result in the following:

<?php

$string = 'foo';
$array = array(
    'foo' => array(
        'bar' => 'baz',
        //expected structure
        //'bar' => array('baz' => array('values'))
));

var_dump(
    isset($string['foo']), //true
    isset($string[0][0]), //false, true in 5.4
    isset($array['foo']['bar'][0]), //true
    isset($array['foo']['bar']['baz']), //true
    isset($array['foo']['bar']['baz']['0']) //false, true as of 5.4
    isset($string['foo']['bar']['baz']['0']) //false, true as of 5.4
);

If so, then it's a major BC break.
Maybe it's a bugfix, but it's a bugfix that allows for behaviour that
1. doesn't really make sense
2. has little to no practical benefit (when are you ever going to be
chaining offsets on strings?)
3. introduces new, hard-to-detect bugs in live code.

What used to be a one-liner, now effectively needs a crapload of
boilerplate code.
If you want this fix to be palatable, we'll need a new language
construct that effectively runs a series of is_array && array_key_exists
with a final !== null check.

array_isset($string['foo']['bar']) //false (not an array)
array_isset($array['foo']['bar']) //true, 'foo' is an array, and 'bar'
is not null
array_isset($array['foo']['bar'][0]) //false, $array['foo']['bar'] is
not an array
array_isset($array['foo']['bar']['baz']) //false, $array['foo']['bar']
is not an array

Behaviour is different from 5.3's isset, but is more in-line with what I
and I believe most PHP programmers would expect isset to behave when
checking multi-dimensional arrays, and has the features, that
array_key_exists is missing.

Anybody got a better idea?

Cheers,
David

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to