# ArrayAccess/ArrayObject return by reference

- Thread: https://externals.io/message/65695
- Original archive: https://news-web.php.net/php.internals/65695
- Started by Mike Willbanks on 2013-02-06T15:27:14+00:00
- Messages: 6
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #65695 — Mike Willbanks — 2013-02-06T15:27:14+00:00

URL: https://externals.io/message/65695#65695

Looking at: http://lxr.php.net/xref/PHP_5_5/Zend/zend_interfaces.c#538 it
seems that ArrayAccess at the moment can not be returned by a reference.
 I'm wondering if there was a technical reason behind this or if it is now
a BC reason?

Anyhow; I was attempting to dig through the source code a bit more last
night to see why ArrayObject could not overload the function declaration of
offsetGet to force a return by reference aka: function &offsetGet($key)...
which works now for ArrayAccess but not for ArrayObject.  I believe it has
to deal with ArrayObject inheriting ArrayAccess?  Is there a way to allow
ArrayObject to change the function declaration in this way?  My PHP
internals skills are not the best which is the reason for the question.

Anyhow; justification wise: in userland this leads to a lot of wtf factor.
 It really comes down to having to provide our own implementation of
ArrayObject by extending several different areas including ArrayAccess so
that references can be returned so multi-dimensional arrays can be properly
unset aka:
$ar = new ArrayObject(array('foo' => array('bar' => array('baz' =>
'foo'))));
unset($ar['foo']['bar']['baz']);

Regards,

Mike

---

## #65696 — Etienne Kneuss — 2013-02-06T16:42:39+00:00

URL: https://externals.io/message/65695#65696 · In reply to: #65695

I assume it would be possible technically but might break (at least by
issuing E_STRICT) a lot of code if we forced ArrayObject::offsetGet to
return a reference.

Think of all the subclasses that extend ArrayObject who currently do not do
that?

Other than that, returning a ref where it previously didn't can have all
kinds of undesirable and hard-to-track consequences.

Best,




> Looking at: http://lxr.php.net/xref/PHP_5_5/Zend/zend_interfaces.c#538 it
> seems that ArrayAccess at the moment can not be returned by a reference.
>  I'm wondering if there was a technical reason behind this or if it is now
> a BC reason?
>
> Anyhow; I was attempting to dig through the source code a bit more last
> night to see why ArrayObject could not overload the function declaration of
> offsetGet to force a return by reference aka: function &offsetGet($key)...
> which works now for ArrayAccess but not for ArrayObject.  I believe it has
> to deal with ArrayObject inheriting ArrayAccess?  Is there a way to allow
> ArrayObject to change the function declaration in this way?  My PHP
> internals skills are not the best which is the reason for the question.
>
> Anyhow; justification wise: in userland this leads to a lot of wtf factor.
>  It really comes down to having to provide our own implementation of
> ArrayObject by extending several different areas including ArrayAccess so
> that references can be returned so multi-dimensional arrays can be properly
> unset aka:
> $ar = new ArrayObject(array('foo' => array('bar' => array('baz' =>
> 'foo'))));
> unset($ar['foo']['bar']['baz']);
>
> Regards,
>
> Mike
>



-- 
Etienne Kneuss
http://www.colder.ch

---

## #65697 — Anthony Ferrara — 2013-02-06T16:47:15+00:00

URL: https://externals.io/message/65695#65697 · In reply to: #65696

Perhaps there's another way out of this. A simple way would be to introduce
an ArrayAccessReference interface in core that adds the references to the
getters/setters...

It's perhaps not the cleanest, but it solves the BC issues...

Anthony




> I assume it would be possible technically but might break (at least by
> issuing E_STRICT) a lot of code if we forced ArrayObject::offsetGet to
> return a reference.
>
> Think of all the subclasses that extend ArrayObject who currently do not do
> that?
>
> Other than that, returning a ref where it previously didn't can have all
> kinds of undesirable and hard-to-track consequences.
>
> Best,
>
>
> 
>
> > […]
> now
> > […]
> of
> > […]
> &offsetGet($key)...
> > […]
> has
> > […]
> factor.
> > […]
> properly
> > […]
>
>
>
> --
> Etienne Kneuss
> http://www.colder.ch

---

## #65698 — Tyler Sommer — 2013-02-06T17:09:42+00:00

URL: https://externals.io/message/65695#65698 · In reply to: #65697

How would the interface enforce returning a reference?




> Perhaps there's another way out of this. A simple way would be to introduce
> an ArrayAccessReference interface in core that adds the references to the
> getters/setters...
> 
> It's perhaps not the cleanest, but it solves the BC issues...
> 
> Anthony
> 
> 
> 
> 
> > […]

---

## #65699 — Anthony Ferrara — 2013-02-06T17:15:33+00:00

URL: https://externals.io/message/65695#65699 · In reply to: #65698

Tyler,

References are indicated by the function signature, so:

interface ArrayAccessReference {
    public function &offsetGet($key);
    public function offsetSet($key, $value);
    public function offsetIsset($key);
    public function offsetUnset($key);
}




> How would the interface enforce returning a reference?
>
>
> 
>
> > […]
> introduce
> > […]
> not do
> > […]
> wrote:
> > […]
> http://lxr.php.net/xref/PHP_5_5/Zend/zend_interfaces.c#538it
> > […]
> reference.
> > […]
> declaration
> > […]
> allow
> > […]
> so
> > […]

---

## #65701 — Gustavo Lopes — 2013-02-06T17:53:18+00:00

URL: https://externals.io/message/65695#65701 · In reply to: #65697

On Wed, 06 Feb 2013 17:47:15 +0100, Anthony Ferrara <ircmaxell@gmail.com>  
wrote:

> Perhaps there's another way out of this. A simple way would be to  
> introduce an ArrayAccessReference interface in core that adds the  
> references to the
> getters/setters...
>
> It's perhaps not the cleanest, but it solves the BC issues...

How would this solve anything? The BC problem is that ArrayObject doesn't  
return by reference. If we made it return by reference, almost all* the  
now valid subclasses that also do not return by reference would issue an  
E_STRICT.

*"almost" because you can override ArrayObject's offsetGet and return by  
reference. Those would be compatible with the modification in ArrayObject.  
We've allowed overrides to return by reference when the parent doesn't for  
quite a while now.

-- 
Gustavo Lopes
