@@ -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,9 +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- ) {
111+ } elseif ($ value instanceof \Serializable || $ value instanceof \__PHP_Incomplete_Class) {
124112 ++$ objectsCount ;
125113 $ objectsPool [$ value ] = [$ id = \count ($ objectsPool ), serialize ($ value ), [], 0 ];
126114 $ value = new Reference ($ id );
@@ -144,16 +132,15 @@ public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount
144132 $ i = 0 ;
145133 $ n = (string ) $ name ;
146134 if ('' === $ n || "\0" !== $ n [0 ]) {
147- $ p = $ reflector ->hasProperty ($ n ) ? $ reflector ->getProperty ($ n ) : null ;
148- $ 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 ' ;
149141 } elseif ('* ' === $ n [1 ]) {
150142 $ n = substr ($ n , 3 );
151143 $ c = $ reflector ->getProperty ($ n )->class ;
152- if ('Error ' === $ c ) {
153- $ c = 'TypeError ' ;
154- } elseif ('Exception ' === $ c ) {
155- $ c = 'ErrorException ' ;
156- }
157144 } else {
158145 $ i = strpos ($ n , "\0" , 2 );
159146 $ c = substr ($ n , 1 , $ i - 1 );
@@ -166,8 +153,14 @@ public static function prepare($values, $objectsPool, &$refsPool, &$objectsCount
166153 }
167154 unset($ sleep [$ name ], $ sleep [$ n ]);
168155 }
169- if (! \array_key_exists ( $ name , $ proto ) || $ proto [ $ name ] !== $ v || "\x00Error \x00trace " === $ name || "\x00Exception \x00trace " === $ name ) {
156+ if ("\x00Error \x00trace " === $ name || "\x00Exception \x00trace " === $ name ) {
170157 $ 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 ;
171164 }
172165 }
173166 if ($ sleep ) {
0 commit comments