rfc:to-array

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
rfc:to-array [2019/12/04 18:23] stevenwadejrrfc:to-array [2020/02/11 13:04] – Update error message comment stevenwadejr
Line 3: Line 3:
   * Date: 2019-08-28   * Date: 2019-08-28
   * Author: Steven Wade, stevenwadejr@gmail.com   * Author: Steven Wade, stevenwadejr@gmail.com
-  * Status: Draft+  * Status: Under Discussion
   * First Published at: http://wiki.php.net/rfc/to-array   * First Published at: http://wiki.php.net/rfc/to-array
  
 ===== Introduction ===== ===== Introduction =====
-PHP contains many [[https://www.php.net/manual/en/language.oop5.magic.php|magic methods]] that give a class greater control over its interaction with the language. The methods [[https://wiki.php.net/rfc/custom_object_serialization|__serialize() and __unserialize()]] give a class control over how it is serialized, <nowiki>__clone()</nowiki> allows control over how self copies are made, and <nowiki>__toString()</nowiki> allows a class to control how it is represented when converted to a string.  
  
 This RFC proposes to add a new magic method called <nowiki>__toArray()</nowiki> to allow a class to control how it is represented when converted to an array. This RFC proposes to add a new magic method called <nowiki>__toArray()</nowiki> to allow a class to control how it is represented when converted to an array.
 +
 +PHP contains many [[https://www.php.net/manual/en/language.oop5.magic.php|magic methods]] that give a class greater control over its interaction with the language. The methods [[https://wiki.php.net/rfc/custom_object_serialization|__serialize() and __unserialize()]] give a class control over how it is serialized, <nowiki>__clone()</nowiki> allows control over how self copies are made, and <nowiki>__toString()</nowiki> allows a class to control how it is represented when converted to a string. Adding a <nowiki>__toArray()</nowiki> method gives developers the ability to transform a class to an array in similar fashion.
  
 ===== Proposal ===== ===== Proposal =====
Line 43: Line 44:
  
 <code php> <code php>
-print_r($person); // calls __toArray() 
- 
-// Output 
-/* 
-Array 
-( 
-    [name] => John Doe 
-    [email] => j.doe@example.com 
-) 
-*/ 
- 
 $personArray = (array) $person; // casting triggers __toArray() $personArray = (array) $person; // casting triggers __toArray()
 </code> </code>
  
 ==== What this is ==== ==== What this is ====
-The example above shows the method <nowiki>__toArray()</nowiki> used in a type-casting context.  This proposal would have objects implementing the <nowiki>__toArray()</nowiki> magic method called within //any// array context including type hinting and return types.+The example above shows the method <nowiki>__toArray()</nowiki> used in a type-casting context.  This proposal would have objects implementing the <nowiki>__toArray()</nowiki> magic method called within //any// array context including type hinting and return types (only when using weak typing - strong typing will throw an error).
  
 Similar to PHP's current implementation of <nowiki>__toString()</nowiki>, a copy of the given object's value as an array is made upon conversion. Similar to PHP's current implementation of <nowiki>__toString()</nowiki>, a copy of the given object's value as an array is made upon conversion.
Line 105: Line 95:
  
 <code php> <code php>
-print_r(array_keys($person));+print_r( 
 +    array_keys($person) 
 +);
  
 // Output // Output
Line 115: Line 107:
 ) )
 */ */
 +</code>
 +
 +=== Strict Types ===
 +
 +Automatic casting will not work when using strict types.
 +
 +<code php>
 +declare(strict_types=1);
 +
 +function bar(Person $person): array {
 +    return $person;
 +}
 +
 +bar($person); // Throws an error: "Return value of bar() must be of the type array, object returned"
 +
 +function foo(array $person) {
 +    var_dump($person);
 +}
 +
 +foo($person); // Throws an error: "Argument 1 passed to foo() must be of the type array, object given"
 +</code>
 +
 +Manual casting within strict types will continue to work and is allowed.
 +
 +<code php>
 +declare(strict_types=1);
 +
 +function bar(Person $person): array {
 +    return (array) $person;
 +}
 +
 +bar($person); // Returns an array
 +
 +function foo(array $person) {
 +    var_dump($person);
 +}
 +
 +foo((array) $person); // Allowed
 </code> </code>
  
Line 123: Line 153:
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
-:?: Help needed+None
  
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
Line 137: Line 167:
 ==== To Opcache ==== ==== To Opcache ====
 :?: Help needed :?: Help needed
 +
 +===== Concerns =====
 +
 +A [[https://externals.io/message/105589#105594|concern raised in the initial RFC proposal discussion]] referred to the existing behavior of casting and exposing object state:
 +
 +>As it currently stands, the array cast is the only operation capable of exposing object state without triggering any kind of access guards: it is very much required for anything that works with reflection and typed properties, and possibly the only operation in PHP that operates on state without some contraption intercepting its execution.
 +
 +As a response to this concern, the new <nowiki>get_mangled_object_vars()</nowiki> function was added in [[https://github.com/php/php-src/commit/eecd8961d94c50cc6cdc94ec80df8c1ce4881a76|PHP 7.4]].
  
 ===== Proposed Voting Choices ===== ===== Proposed Voting Choices =====
Line 145: Line 183:
  
 ===== References ===== ===== References =====
-* PHP Manual: [[https://www.php.net/manual/en/language.oop5.magic.php|magic methods]], [[https://www.php.net/manual/en/ref.array.php|Array Functions]], [[https://www.php.net/manual/en/class.arrayaccess.php|ArrayAccess]] .  +  * PHP Manual: [[https://www.php.net/manual/en/language.oop5.magic.php|magic methods]], [[https://www.php.net/manual/en/ref.array.php|Array Functions]], [[https://www.php.net/manual/en/class.arrayaccess.php|ArrayAccess]] .  
-* PHP RFC: [[https://wiki.php.net/rfc/custom_object_serialization|New custom object serialization mechanism]] .  +  * PHP RFC: [[https://wiki.php.net/rfc/custom_object_serialization|New custom object serialization mechanism]] .  
-* Initial idea and discussion: [[https://externals.io/message/105589]] . +  * Initial idea and discussion: [[https://externals.io/message/105589]] . 
  
 ===== Rejected Features ===== ===== Rejected Features =====
  
rfc/to-array.txt · Last modified: 2020/02/11 13:57 by stevenwadejr