It was on design. list() was intended to support plain arrays only.

Thanks. Dmitry.

On Fri, Sep 26, 2014 at 12:45 AM, Nikita Popov <nikita....@gmail.com> wrote:

> On Thu, Sep 25, 2014 at 10:32 PM, Nikita Popov <nikita....@gmail.com>
> wrote:
>
>> On Thu, Sep 25, 2014 at 1:15 PM, Dmitry Stogov <dmi...@zend.com> wrote:
>>
>>> disabling string handling would allow make operation simpler and would
>>> improve regular access to array elements.
>>> We won't need to check for (opline->extended_value & ZEND_FETCH_ADD_LOCK)
>>> in FETCH_DIM_R handler.
>>> However, it's going to be very small improvement, and I don't care a
>>> lot. :)
>>>
>>> enabling string handling would require complication of
>>> ZEND_FETCH_DIM_TMP_VAR handler (for strings support).
>>> It's going to make list() handling a bit slower, but not significantly.
>>>
>>> my choice +1 for disabling.
>>>
>>
>> Could you please clarify why removing string support would make the
>> operation simpler? I voted for always supporting strings because I thought
>> that is the option that simplifies things - in particular it would allow
>> use to drop the FETCH_DIM_TMP_VAR opcode and always go through FETCH_DIM_R
>> instead. Sample patch here:
>> https://github.com/nikic/php-src/compare/stringOffsetsInList Or did I
>> miss something and we can't do that?
>>
>> Nikita
>>
>
> I'd like to add that the FETCH_DIM_TMP_VAR opcode also provides incorrect
> results if objects are used. list() generally accepts objects implementing
> ArrayAccess, but if the object happens to be a TMP_VAR and
> FETCH_DIM_TMP_VAR is used instead of FETCH_DIM_R, you'll just get a NULL
> result:
>
> <?php
>
> class Arr implements ArrayAccess {
>     private $arr;
>     public function offsetGet($k) { return $this->arr[$k]; }
>     public function offsetSet($k, $v) { $this->arr[$k] = $v; }
>     public function offsetExists($k) { return isset($this->arr[$k]); }
>     public function offsetUnset($k) { unset($this->arr[$k]); }
> }
>
> $arr = new Arr;
> $arr[0] = 'foo';
> $arr[1] = 'bar';
>
> list($a, $b) = $arr;
> var_dump($a, $b); // foo, bar
>
> // (object) forces TMP_VAR
> list($a, $b) = (object) $arr;
> var_dump($a, $b); // NULL, NULL
>
> So to handle that case we'd already have to extend the FETCH_DIM_TMP_VAR
> handler to support objects in addition to arrays. At which point I don't
> really see the point of making this a special case and would always use
> FETCH_DIM_R instead (which already has all the necessary code to support
> arrays, objects and strings).
>
> Nikita
>

Reply via email to