I'm developing a class that is a collection of values. In it I have several methods that filter the values contained in this collection. My intention is to return a new instance of this same class depending on the modification that a given method makes to the items contained in that collection.
Generally, when I see classes development in PHP, it is not very common to do this, since the $this
is usually returned to refer to classe
current.
To illustrate my doubt, I'll demonstrate a collection as an example:
class Collection
{
protected $items = [];
public function __construct(array $items = [])
{
$this->items = $items;
}
public function filter(\Closure $callback)
{
$this->items = array_filter($this->items, $callback);
return $this;
}
public function map(\Closure $callback)
{
$this->items = array_map($callback, $this->items, array_keys($this->items));
return $this;
}
}
Notice that with each method, the values of $items
are changed and the instance itself is returned.
But I've seen Laravel's Illuminate \ Support \ Collection class, some method in the Collection classes that do something a little different: Instead of returning the instance itself, a new instance is returned for the modified values.
class Collection
{
protected $items = [];
public function __construct(array $items = [])
{
$this->items = $items;
}
public function filter(\Closure $callback)
{
return new static(array_filter($this->items, $callback));
}
public function map(\Closure $callback)
{
$items = array_map($callback, $this->items, array_keys($this->items));
return new static($items);
}
}
Note that in the second example, new static
is used instead of $this
.
I understand very well that this operation causes the values to be passed on in a new way, but without changing the original reference. Some cases this is very helpful.
About this difference, I would like to know:
-
Is there a name for this particular pattern / behavior in the class of the second example?
-
Using this
new static
would not be a structural problem, since if I inherit this class, can I change the constructor, andnew static
would be impaired, having to be changed in all methods? >
Update
To illustrate the second question, let me give you an example. Suppose I wanted to inherit the Collection
class to create new features for it. In this new class I want to add two new parameters to construtor
.
class KeyValueCollection extends Collection
{
public function __construct(array $keys, array $values)
{
parent::construct(array_combine($keys, $values));
}
}
When I call the KeyValueCollection::filter
method inherited by Collection
, an error will be generated, as new static
is now referring to KeyValueCollection
, which require two parameters in the constructor, not one.
KeyValueCollection::__construct(array $keys, array $values);
If you use new static
is not to modify the class itself, how could you work around this problem, since in the first case, Collection::__construct
needs a parameter.
If you need such an operation, would I have to modify all methods of the inherited class?