rfc:to-array

PHP RFC: __toArray()

Introduction

This RFC proposes to add a new magic method called __toArray() to allow a class to control how it is represented when converted to an array.

PHP contains many magic methods that give a class greater control over its interaction with the language. The methods __serialize() and __unserialize() give a class control over how it is serialized, __clone() allows control over how self copies are made, and __toString() allows a class to control how it is represented when converted to a string. Adding a __toArray() method gives developers the ability to transform a class to an array in similar fashion.

Proposal

Example:

class Person
{
    protected $name;
    protected $email;
 
    public $foo = 'bar';
 
    public function __construct(string $name, string $email)
    {
        $this->name = $name;
        $this->email  = $email;
    }
 
    public function __toArray()
    {
        return [
            'name' => $this->name,
            'email'  => $this->email,
        ];
    }
}
 
$person = new Person('John Doe', 'j.doe@example.com');

Example usage:

print_r($person); // calls __toArray()
 
// Output
/*
Array
(
    [name] => John Doe
    [email] => j.doe@example.com
)
*/
 
$personArray = (array) $person; // casting triggers __toArray()

What this is

The example above shows the method __toArray() used in a type-casting context. This proposal would have objects implementing the __toArray() magic method called within any array context including type hinting and return types.

Similar to PHP's current implementation of __toString(), a copy of the given object's value as an array is made upon conversion.

Type Hinting

function foo(array $person) {
    var_dump($person);
}
 
// Output
/*
array(2) {
  ["name"]=>
  string(8) "John Doe"
  ["email"]=>
  string(17) "j.doe@example.com"
}
*/

Return Type

function bar(Person $person): array {
    return $person;
}
 
var_dump(bar($person));
 
// Output
/*
array(2) {
  ["name"]=>
  string(8) "John Doe"
  ["email"]=>
  string(17) "j.doe@example.com"
}
*/

array_* and built-in functions

The array operating functions listed on the Array Functions would first convert an object implementing the __toArray() method before continuing operations.

print_r(array_keys($person));
 
// Output
/*
Array
(
    [0] => first
    [1] => email
)
*/

What this is not

This proposal does not allow accessing and setting values as you would in a normal array, that functionality remains with classes implementing the ArrayAccess interface.

Array functions that operate on an array by reference such as sort or shuffle will not work on an object implementing __toArray() under this proposal.

Backward Incompatible Changes

:?: Help needed

Proposed PHP Version(s)

Next PHP version (target 8.0)

RFC Impact

To SAPIs

:?: Help needed

To Existing Extensions

:?: Help needed

To Opcache

:?: Help needed

Proposed Voting Choices

Vote will require 2/3 majority

Patches and Tests

No patch exists yet. A proof of concept for type casting was created by Sara Golemon, but no official patch has been created. Will need help with this.

References

Rejected Features

rfc/to-array.txt · Last modified: 2019/12/10 14:24 by stevenwadejr