rfc:to-array

Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
rfc:to-array [2019/12/04 17:59]
stevenwadejr
rfc:to-array [2020/02/11 13:57] (current)
stevenwadejr Bump the version number now that it's under discussion and some feedback has been addressed
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 101: Line 91:
  
 **array_*  and built-in functions** **array_*  and built-in functions**
 +
 +The array operating functions listed on the [[https://www.php.net/manual/en/ref.array.php|Array Functions]] would first convert an object implementing the <nowiki>__toArray()</nowiki> method before continuing operations.
  
 <code php> <code php>
 +print_r(
 +    array_keys($person)
 +);
  
 +// Output
 +/*
 +Array
 +(
 +    [0] => first
 +    [1] => email
 +)
 +*/
 +</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>
  
 ==== What this is not ==== ==== What this is not ====
-Discuss what the RFC does not cover (accessing and setting values as  you would in a normal array.+This proposal does not allow accessing and setting values as you would in a normal array, that functionality remains with classes implementing the [[https://www.php.net/manual/en/class.arrayaccess.php|ArrayAccess]] interface. 
 + 
 +Array functions that operate on an array by reference such as <nowiki>sort</nowiki> or <nowiki>shuffle</nowiki> will not work on an object implementing <nowiki>__toArray()</nowiki> under this proposal.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
-What breaks, and what is the justification for it?+None
  
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
Line 117: Line 160:
 ===== RFC Impact ===== ===== RFC Impact =====
 ==== To SAPIs ==== ==== To SAPIs ====
-Describe the impact to CLI, Development web server, embedded PHP etc.+:?: Help needed
  
 ==== To Existing Extensions ==== ==== To Existing Extensions ====
-Will existing extensions be affected?+:?: Help needed
  
 ==== To Opcache ==== ==== To Opcache ====
-It is necessary to develop RFC's with opcache in mind, since opcache is a core extension distributed with PHP.+:?: Help needed
  
-Please explain how you have verified your RFC's compatibility with opcache.+===== Concerns =====
  
-===== Open Issues ===== +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:
-Make sure there are no open issues when the vote starts!+
  
-===== Unaffected PHP Functionality ===== +>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.
-List existing areas/features of PHP that will not be changed by the RFC.+
  
-This helps avoid any ambiguityshows that you have thought deeply about the RFC's impact, and helps reduces mail list noise. +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]].
- +
-===== Future Scope ===== +
-This section details areas where the feature might be improved in future, but that are not currently proposed in this RFC.+
  
 ===== Proposed Voting Choices ===== ===== Proposed Voting Choices =====
-Include these so readers know where you are heading and can discuss the proposed voting options.+Vote will require 2/3 majority
  
 ===== Patches and Tests ===== ===== Patches and Tests =====
-Links to any external patches and tests go here. +No patch exists yetA [[https://github.com/sgolemon/php-src/tree/experimental.toarray|proof of concept]] for type casting was created by Sara Golemonbut no official patch has been created Will need help with this.
- +
-If there is no patch, make it clear who will create a patch, or whether a volunteer to help with implementation is needed. +
- +
-Make it clear if the patch is intended to be the final patch, or is just a prototype. +
- +
-For changes affecting the core languageyou should also provide a patch for the language specification. +
- +
-===== Implementation ===== +
-After the project is implemented, this section should contain  +
-  - the version(s) it was merged into +
-  - a link to the git commit(s) +
-  - a link to the PHP manual entry for the feature +
-  - a link to the language specification section (if any)+
  
 ===== References ===== ===== References =====
-Links to external referencesdiscussions or RFCs+  * 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]] .  
 +  * Initial idea and discussion: [[https://externals.io/message/105589]] . 
  
 ===== Rejected Features ===== ===== Rejected Features =====
-Keep this updated with features that were discussed on the mail lists.+
rfc/to-array.1575482386.txt.gz · Last modified: 2019/12/04 17:59 by stevenwadejr