Enabling ArrayObject et.al. to fully replace array usage
| From: | Mike Schinkel | Date: | Mon, 18 Nov 2019 18:23:03 +0000 |
| Subject: | Enabling ArrayObject et.al. to fully replace array usage | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-107823@lists.php.net to get a copy of this message | ||
I decided to create a new thread since I was diverging the topic.
> On Nov 18, 2019, at 5:36 AM, Michał Brzuchalski <michal.brzuchalski@gmail.com> wrote:
> Currently, arrays all together with rest of scalar types are value-types
> which means when they're passed on (unless passed by a reference) their copies are
> modified but not the original one.
> That's cause object's in PHP are reference types, when passed they're always
> passed by reference.
> Thus making a general ArrayObject class even internally for now should follow value-types
> semantics.
> How do you want to reconcile that?
Excellent point.
Would it not be possible to automatically do a clone on pass when __asArray()===true, such as this:
<?php
function setBar($foo,$newbar) {
$foo->bar = $newbar;
}
class Foo extends ArrayObject {
public $bar;
private $as_array = true;
function __asArray(){
return $this->as_array;
}
function setAsArray($as_array){
$this->as_array = $as_array;
}
}
// PHP 7.x
$foo = new Foo();
$foo->bar = 'baz';
setBar(clone $foo,'bazoom');
echo $foo->bar; // outputs: baz
setBar($foo,'bazoom');
echo $foo->bar; // outputs: bazoom
// PHP 8.x (maybe?)
$foo = new Foo();
$foo->bar = 'baz';
setBar($foo,'bazoom');
echo $foo->bar; // outputs: baz
$foo->setAsArray(false);
setBar($foo,'bazoom');
echo $foo->bar; // outputs: bazoom
> Another thing is when shaping an OO API on general array class -> ArrayObject all of the
> existing array_xxx
> functions IMO should be deprecated and that's not likely gonna happen.
Are you saying that ideally we'd have $array->map($callable) instead of
array_map($callable,$array)?
Totally agree, but I'd rather have array_map() work with ArrayObject than wait for a
"perfect" API that may never come.
> If you ask me why I think like that, well if ArrayObject is going to be automatically served
> from all arrays
> keeping array_xxx functions makes no longer a sense, the only thing they could do from that
> point
> is only calling an ArrayObject method, which is different from what they do now they return a
> new value-type
> a new array with filtered, mapped key-value array elements, when working with objects you
> expect
> them to mutate themself if they're mutable or return a brand new instance when
> they're immutable.
I think it definitely makes sense, because backward compatibility.
We could easily layer a better API on later, assuming opt-in via interface so that no BC would
occur.
> maybe there is an additional initialization needed besides of key-value pairs only, for eg.
> additional constructor argument. ... If that happens for internal array_xxx functions it would be
> hard to guess how to create a new instance,
> they'd become a thin wrapper of calling ArrayObject like methods, nothing more.
In the case of userland code extending ArrayObject or its related interfaces could it not simply
leverage __clone() if it needs to create a new instance of self to address that concern?
-Mike