I would like to modify my initial concept of an "arrayable" type because
PHP core developers seems to be in favor of the upcoming union data
types instead of adding a new "arrayable" pseudo type similar to "iterable".

So, I would like to propose an "Arrayable" interface that combines
ArrayAccess, Countable and Traversable interfaces and adds a toArray()
method:

interface Arrayable extends ArrayAccess, Countable, Traversable
{
    public function toArray() : array;
}

Then, methods signatures can support array and Array-like objects:

function useArrayable( array|Arrayable $arg ) : array|Arrayable {
    $cnt = count( $arg );
    $value = $arg['key'];
    foreach( $arg as $key => $entry );
    is_object( $arg ) { $nativeArray = $arg->toArray(); }
    return $arg;
}

Adding a toArray() method also avoids controversy around using a magic
__toArray() method, even if this would be easier for developers in this
case.

If union data types are available and "iterable" is implemented as
alias, an alias "arrayable" for "array|Arrayable" may be added as well.


Am 19.11.19 um 23:21 schrieb Aimeos | Norbert Sendetzky:
> Since PHP 7.1, there's the "iterable" pseudo type hint that matches
> "array" or "Traversable".
> 
> PHP frameworks would profit from support of an "arrayable" pseudo type
> hint that matches "array" and all objects that can be used like arrays.
> 
> For that, "arrayable" objects have to implement these interfaces:
> - ArrayAccess
> - Countable
> - Traversable (i.e. either Iterator or IteratorAggregate)
> 
> 
> Implementing "arrayable" pseudo type, we could pass arrays or all
> objects that can be used like arrays to methods and do:
> 
> function useArrayable( arrayable $arg ) : arrayable {
>     $cnt = count( $arg );
>     $value = $arg['key'];
>     foreach( $arg as $key => $entry );
>     return $arg;
> }
> 
> 
> Best use cases are:
> 
> - Laravel Collection
> (https://github.com/laravel/framework/blob/6.x/src/Illuminate/Support/Collection.php)
> 
> - Aimeos Map (https://github.com/aimeos/map)
> 
> 
> No new interface is proposed because we can check if objects implement:
> 
> ArrayAccess && Countable && Traversable
> 
> 
> Because "array" !== "arrayable", "arrayable objects will not be accepted
> by array_* functions and all functions that only use "array" as type
> hint for parameters and return types.
> 
> 
> This proposal is not obsolete by the implementation of union types (i.e.
> array|Traversable) because union data types are types/interfaces
> combined by OR. "arrayable" is a combination of OR and AND:
> 
> array|ArrayAccess&Countable&Traversable
> 
> 
> Also, "arrayable" won't supersede "iterable" because
> 
> - "iterable" matches arrays, iterators and generators
> 
> - "arrayable" matches arrays and objects that can be used like arrays
> 
> 
> "Can be used like arrays" doesn't include support for empty() because it
> works for empty arrays but not for "arrayable" objects without elements.
> If possible and requested, this may be addressed by another RFC.
> 
> 
> As Larry Garfield suggested, this pre-RFC proposes concentrates on the
> "arrayable" pseudo type only.
> 
> It does NOT discusses that:
> 
> - arrayable objects can be converted to arrays (Steven Wade works on an
> RFC for a __toArray() magic function)
> 
> - ArrayObject or any other arrayable object makes the array_* functions
> less relevant in the future
> 
> - arrayable objects can be passed to array_* functions in the future
> 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to