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
rfc:to-array [2019/12/04 18:23] stevenwadejrrfc:to-array [2020/02/11 13:57] (current) – Bump the version number now that it's under discussion and some feedback has been addressed stevenwadejr
Line 1: Line 1:
 ====== PHP RFC: __toArray() ====== ====== PHP RFC: __toArray() ======
-  * Version: 0.1+  * Version: 1.1
   * 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 =====
rfc/to-array.1575483822.txt.gz · Last modified: 2019/12/04 18:23 by stevenwadejr