rfc:custom_object_serialization

Differences

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

Link to this comparison view

Next revision
Previous revision
rfc:custom_object_serialization [2019/01/24 12:08] – created nikicrfc:custom_object_serialization [2019/03/22 09:43] (current) – Implemented nikic
Line 2: Line 2:
   * Date: 2019-01-24   * Date: 2019-01-24
   * Author: Nikita Popov <nikic@php.net>   * Author: Nikita Popov <nikic@php.net>
-  * Status: Under Discussion +  * Status: Implemented (in PHP 7.4)
-  * Target Version: PHP 7.4+
   * Implementation: https://github.com/php/php-src/pull/3761   * Implementation: https://github.com/php/php-src/pull/3761
  
Line 14: Line 13:
 ==== Serializable ==== ==== Serializable ====
  
-Classes implementing the ''Serializable'' interface are encoded using the ''C'' format, which is basically ''C:ClassNameLen:"ClassName":PayloadLen:{Payload}'', where the ''Payload'' is an arbitrary string. This is the string returned by ''Serializable::serialize()'' and almost always produced by a nested call to ''serialize()'':+Classes implementing the ''Serializable'' interface are encoded using the ''C'' format, which is basically ''%%C:ClassNameLen:"ClassName":PayloadLen:{Payload}%%'', where the ''Payload'' is an arbitrary string. This is the string returned by ''Serializable::serialize()'' and almost always produced by a nested call to ''serialize()'':
  
 <code php> <code php>
Line 75: Line 74:
 ===== Proposal ===== ===== Proposal =====
  
-The proposed serialization mechanism tries to combine the generality of ''Serializable'' with the general implementation approach of ''%%__sleep()%%''/''%%__wakeup()%%''.+The proposed serialization mechanism tries to combine the generality of ''Serializable'' with the implementation approach of ''%%__sleep()%%''/''%%__wakeup()%%''.
  
 Two new magic methods are added: Two new magic methods are added:
Line 87: Line 86:
 </code> </code>
  
-The usage is very similar to the ''Serializable'' interface. From a practical perspective the main difference is that instead of calling ''serialize()'' inside ''Serializable::serialize()'', you directly the data that should be serialized as an array.+The usage is very similar to the ''Serializable'' interface. From a practical perspective the main difference is that instead of calling ''serialize()'' inside ''Serializable::serialize()'', you directly return the data that should be serialized as an array.
  
 The following example illustrates how ''%%__serialize()%%''/''%%__unserialize()%%'' are used, and how they compose under inheritance: The following example illustrates how ''%%__serialize()%%''/''%%__unserialize()%%'' are used, and how they compose under inheritance:
Line 128: Line 127:
 ==== Magic methods vs interface ==== ==== Magic methods vs interface ====
  
-This RFC proposed the addition of new magic methods, but using an interface instead would also be possible, though will require some naming gymnastics to avoid ''RealSerializable''.+This RFC proposes the addition of new magic methods, but using an interface instead would also be possible, though it will require some naming gymnastics to avoid ''RealSerializable''.
  
-This proposal uses magic methods because they interoperate well. ''%%__serialize()%%'' and ''%%__unserialize()%%'' can be added to a class without compatibility concerns: They will be used on PHP 7.4 or newer and ignored on PHP 7.3 or older. Using an interface instead requires either raising the version requirement to PHP 7.4, or dealing with the definition of a stub interface in a compatible manner.+This proposal uses magic methods for two reasons. First, they interoperate well. ''%%__serialize()%%'' and ''%%__unserialize()%%'' can be added to a class without compatibility concerns: They will be used on PHP 7.4 or newer and ignored on PHP 7.3 or older. Using an interface instead requires either raising the version requirement to PHP 7.4, or dealing with the definition of a stub interface in a compatible manner
 + 
 +Second, they are semantically more correct. In PHP all objects are serializable by default. The ''Serializable'' interface is a misnomer in that sense, because an object that does not implement ''Serializable'' can be (and usually is) still serializable. On the contrary, ''Serializable'' might be implemented specifically for the purpose of forbidding serialization, by throwing an exception. The magic methods ''%%__serialize()%%'' and ''%%__unserialize()%%'' are just hooks to customize the serialization functionality, they do not determine whether an object can be serialized, and code should generally have no reason to check for their presence or absence.
  
 ==== Creating objects in __unserialize() ==== ==== Creating objects in __unserialize() ====
Line 138: Line 139:
 This would allow an even greater degree of control over the serialization mechanism, for example it would allow to return an already existing object from ''%%__unserialize()%%''. This would allow an even greater degree of control over the serialization mechanism, for example it would allow to return an already existing object from ''%%__unserialize()%%''.
  
-However, allowing this would once again require immediately calling ''%%__unserialize()%%'' functions (interleaved with unserialization) to make the object available for backreferencs, which would reintroduce some of the problems that ''Serializable'' suffers from. As such, this will not be supported.+However, allowing this would once again require immediately calling ''%%__unserialize()%%'' functions (interleaved with unserialization) to make the object available for backreferences, which would reintroduce some of the problems that ''Serializable'' suffers from. As such, this will not be supported.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
Line 146: Line 147:
 ===== Vote ===== ===== Vote =====
  
-Include the proposed serialization mechanism in PHP 7.4? A 2/3 majority will be required.+Voting started 2019-03-01 and ends 2019-03-15. 
 + 
 +<doodle title="Include proposed serialization mechanism in PHP 7.4?" auth="nikic" voteType="single" closed="true"> 
 +   * Yes 
 +   * No 
 +</doodle>
rfc/custom_object_serialization.1548331713.txt.gz · Last modified: 2019/01/24 12:08 by nikic