@@ -76,33 +76,23 @@ public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount
7676 $ class = $ value ::class;
7777 $ reflector = Registry::$ reflectors [$ class ] ??= Registry::getClassReflector ($ class );
7878 $ properties = [];
79+ $ sleep = null ;
80+ $ proto = Registry::$ prototypes [$ class ];
7981
8082 if ($ reflector ->hasMethod ('__serialize ' )) {
8183 if (!$ reflector ->getMethod ('__serialize ' )->isPublic ()) {
8284 throw new \Error (\sprintf ('Call to %s method "%s::__serialize()". ' , $ reflector ->getMethod ('__serialize ' )->isProtected () ? 'protected ' : 'private ' , $ class ));
8385 }
8486
85- if (!\is_array ($ serializeProperties = $ value ->__serialize ())) {
87+ if (!\is_array ($ arrayValue = $ value ->__serialize ())) {
8688 throw new \TypeError ($ class .'::__serialize() must return an array ' );
8789 }
8890
8991 if ($ reflector ->hasMethod ('__unserialize ' )) {
90- $ properties = $ serializeProperties ;
91- } else {
92- foreach ($ serializeProperties as $ n => $ v ) {
93- $ p = $ reflector ->hasProperty ($ n ) ? $ reflector ->getProperty ($ n ) : null ;
94- $ c = $ p && (\PHP_VERSION_ID >= 80400 ? $ p ->isProtectedSet () || $ p ->isPrivateSet () : $ p ->isReadOnly ()) ? $ p ->class : 'stdClass ' ;
95- $ properties [$ c ][$ n ] = $ v ;
96- }
92+ $ properties = $ arrayValue ;
93+ goto prepare_value;
9794 }
98-
99- goto prepare_value;
100- }
101-
102- $ sleep = null ;
103- $ proto = Registry::$ prototypes [$ class ];
104-
105- if (($ value instanceof \ArrayIterator || $ value instanceof \ArrayObject) && null !== $ proto ) {
95+ } elseif (($ value instanceof \ArrayIterator || $ value instanceof \ArrayObject) && null !== $ proto ) {
10696 // ArrayIterator and ArrayObject need special care because their "flags"
10797 // option changes the behavior of the (array) casting operator.
10898 [$ arrayValue , $ properties ] = self ::getArrayObjectProperties ($ value , $ proto );
@@ -118,10 +108,7 @@ public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount
118108 }
119109 $ properties = ['SplObjectStorage ' => ["\0" => $ properties ]];
120110 $ arrayValue = (array ) $ value ;
121- } elseif ($ value instanceof \Serializable
122- || $ value instanceof \__PHP_Incomplete_Class
123- || \PHP_VERSION_ID < 80200 && $ value instanceof \DatePeriod
124- ) {
111+ } elseif ($ value instanceof \Serializable || $ value instanceof \__PHP_Incomplete_Class || \PHP_VERSION_ID < 80200 && $ value instanceof \DatePeriod) {
125112 ++$ objectsCount ;
126113 $ objectsPool [$ value ] = [$ id = \count ($ objectsPool ), serialize ($ value ), [], 0 ];
127114 $ value = new Reference ($ id );
@@ -145,16 +132,15 @@ public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount
145132 $ i = 0 ;
146133 $ n = (string ) $ name ;
147134 if ('' === $ n || "\0" !== $ n [0 ]) {
148- $ p = $ reflector ->hasProperty ($ n ) ? $ reflector ->getProperty ($ n ) : null ;
149- $ c = $ p && (\PHP_VERSION_ID >= 80400 ? $ p ->isProtectedSet () || $ p ->isPrivateSet () : $ p ->isReadOnly ()) ? $ p ->class : 'stdClass ' ;
135+ $ parent = $ reflector ;
136+ do {
137+ $ p = $ parent ->hasProperty ($ n ) ? $ parent ->getProperty ($ n ) : null ;
138+ } while (!$ p && $ parent = $ parent ->getParentClass ());
139+
140+ $ c = $ p && (!$ p ->isPublic () || (\PHP_VERSION_ID >= 80400 ? $ p ->isProtectedSet () || $ p ->isPrivateSet () : $ p ->isReadOnly ())) ? $ p ->class : 'stdClass ' ;
150141 } elseif ('* ' === $ n [1 ]) {
151142 $ n = substr ($ n , 3 );
152143 $ c = $ reflector ->getProperty ($ n )->class ;
153- if ('Error ' === $ c ) {
154- $ c = 'TypeError ' ;
155- } elseif ('Exception ' === $ c ) {
156- $ c = 'ErrorException ' ;
157- }
158144 } else {
159145 $ i = strpos ($ n , "\0" , 2 );
160146 $ c = substr ($ n , 1 , $ i - 1 );
@@ -167,8 +153,14 @@ public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount
167153 }
168154 unset($ sleep [$ name ], $ sleep [$ n ]);
169155 }
170- if (! \array_key_exists ( $ name , $ proto ) || $ proto [ $ name ] !== $ v || "\x00Error \x00trace " === $ name || "\x00Exception \x00trace " === $ name ) {
156+ if ("\x00Error \x00trace " === $ name || "\x00Exception \x00trace " === $ name ) {
171157 $ properties [$ c ][$ n ] = $ v ;
158+ } elseif (!\array_key_exists ($ name , $ proto ) || $ proto [$ name ] !== $ v ) {
159+ $ properties [match ($ c ) {
160+ 'Error ' => 'TypeError ' ,
161+ 'Exception ' => 'ErrorException ' ,
162+ default => $ c ,
163+ }][$ n ] = $ v ;
172164 }
173165 }
174166 if ($ sleep ) {
0 commit comments