On Thursday, 4 July 2024 at 14:52, Gina P. Banyard <intern...@gpb.moe> wrote:

> Hello internals,
> 
> I would like to formally open the discussion on an RFC I've been working on 
> for the past year:
> https://wiki.php.net/rfc/container-offset-behaviour
> 

Hello internals,

Ilija did a review of the RFC and pointed out some good questions and remarks.

I've clarified, and amended the implementation, that ArrayAccess extends 
DimensionReadable, DimensioWriteable, and DimensionUnsettable.

I've added to the RFC the deprecation of using integer offsets when using 
ArrayObject with a backing object, as it turns out supporting this adds a lot 
of complexity in the engine that would be great to remove.

One of the new warnings the RFC introduces is when using a bogus value as a 
container in isset()/empty() other than `null` which shortcuts.
This shouldn't cause many issues, except possibly if the container is `false`, 
as it may be the result from an internals function call which returns false on 
failure instead of null.
The question is if `false` should have the same exemption as `null`?

The behaviour around the increment and decrement operators is slightly 
unfortunate.
Incrementing an array offset or object property is treated more like a 
read-write operation, however, due to the lack of VM opcodes, it is treated 
like a fetch for object offsets.
After discussion with Ilija it seems wise to make this an Error for now so that 
we can support it properly in the future, and have the increment observable via 
the offsetSet() method.

There are still a couple of questions around the behaviour of ArrayObject with 
property hooks that I need to look into, especially around the current 
ArrayObject behaviour with ignoring the __set() and __get() magic methods.

The final question, which is somewhat tricky, is how to deal with 
auto-vivification?
The gist can be explained with the following code:

$obj = new Vector();
$ref = &$obj[0];
var_dump($ref);

$obj[1][] = 'append';
$obj[2][50] = 'set-to-offset';

For arrays, $ref would be NULL
And when nesting them, the "null" auto-magically becomes an array.
However, for objects it is not clear what to do, if the fetch() method creates 
an object,
then the initial $ref would already have a auto-vivified container.
However, if NULL is returned, then the nested append and offset write would not 
auto-vivify a nested Vec container, but a standard PHP array.

I currently have a crude prototype where, in the nested dimension case, I 
instantiate a new object of the same type,
but this doesn't call the constructor (which I could do), but passing arguments 
to it is impossible.
Another solution is to add another interface, e.g. Autovivificapable, which 
would define an autovivify() method which would be called in those instances.
Does anyone have any opinions about this?

I have also slightly amended the RFC and added a BC break recap section.
Reminder, the RFC on the Wiki is located here:
https://wiki.php.net/rfc/container-offset-behaviour
And on GitHub here:
https://github.com/Girgias/php-rfcs/blob/master/container-offset-behaviour.md


Best regards,

Gina P. Banyard

Reply via email to