@@ -249,19 +249,25 @@ private function doParse($value, $flags)
249
249
if ('<< ' === $ key ) {
250
250
$ mergeNode = true ;
251
251
$ allowOverwrite = true ;
252
- if (isset ($ values ['value ' ]) && 0 === strpos ( $ values ['value ' ], ' * ' ) ) {
252
+ if (isset ($ values ['value ' ]) && isset ( $ values [ ' value ' ][ 0 ]) && ' * ' === $ values ['value ' ][ 0 ] ) {
253
253
$ refName = substr (rtrim ($ values ['value ' ]), 1 );
254
254
if (!array_key_exists ($ refName , $ this ->refs )) {
255
255
throw new ParseException (sprintf ('Reference "%s" does not exist. ' , $ refName ), $ this ->getRealCurrentLineNb () + 1 , $ this ->currentLine );
256
256
}
257
257
258
258
$ refValue = $ this ->refs [$ refName ];
259
259
260
- if (!is_array ($ refValue )) {
260
+ if (is_array ($ refValue )) {
261
+ $ data += $ refValue ; // array union
262
+ } elseif ((bool ) (Yaml::PARSE_OBJECT_FOR_MAP & $ flags ) && $ refValue instanceof \stdClass) {
263
+ foreach ($ refValue as $ refValueKey => $ refValueValue ) {
264
+ if (!isset ($ data [$ refValueKey ])) {
265
+ $ data [$ refValueKey ] = $ refValueValue ;
266
+ }
267
+ }
268
+ } else {
261
269
throw new ParseException ('YAML merge keys used with a scalar value instead of an array. ' , $ this ->getRealCurrentLineNb () + 1 , $ this ->currentLine );
262
270
}
263
-
264
- $ data += $ refValue ; // array union
265
271
} else {
266
272
if (isset ($ values ['value ' ]) && $ values ['value ' ] !== '' ) {
267
273
$ value = $ values ['value ' ];
@@ -270,25 +276,31 @@ private function doParse($value, $flags)
270
276
}
271
277
$ parsed = $ this ->parseBlock ($ this ->getRealCurrentLineNb () + 1 , $ value , $ flags );
272
278
273
- if (!is_array ($ parsed )) {
274
- throw new ParseException ('YAML merge keys used with a scalar value instead of an array. ' , $ this ->getRealCurrentLineNb () + 1 , $ this ->currentLine );
275
- }
276
-
277
- if (isset ($ parsed [0 ])) {
278
- // If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes
279
- // and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier
280
- // in the sequence override keys specified in later mapping nodes.
281
- foreach ($ parsed as $ parsedItem ) {
282
- if (!is_array ($ parsedItem )) {
283
- throw new ParseException ('Merge items must be arrays. ' , $ this ->getRealCurrentLineNb () + 1 , $ parsedItem );
279
+ if (is_array ($ parsed )) {
280
+ if (isset ($ parsed [0 ])) {
281
+ // If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes
282
+ // and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier
283
+ // in the sequence override keys specified in later mapping nodes.
284
+ foreach ($ parsed as $ parsedItem ) {
285
+ if (!is_array ($ parsedItem )) {
286
+ throw new ParseException ('Merge items must be arrays. ' , $ this ->getRealCurrentLineNb () + 1 , $ parsedItem );
287
+ }
288
+
289
+ $ data += $ parsedItem ; // array union
290
+ }
291
+ } else {
292
+ // If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the
293
+ // current mapping, unless the key already exists in it.
294
+ $ data += $ parsed ; // array union
295
+ }
296
+ } elseif ((bool ) (Yaml::PARSE_OBJECT_FOR_MAP & $ flags ) && $ parsed instanceof \stdClass) {
297
+ foreach ($ parsed as $ parsedKey => $ parsedValue ) {
298
+ if (!isset ($ data [$ parsedKey ])) {
299
+ $ data [$ parsedKey ] = $ parsedValue ;
284
300
}
285
-
286
- $ data += $ parsedItem ; // array union
287
301
}
288
302
} else {
289
- // If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the
290
- // current mapping, unless the key already exists in it.
291
- $ data += $ parsed ; // array union
303
+ throw new ParseException ('YAML merge keys used with a scalar value instead of an array. ' , $ this ->getRealCurrentLineNb () + 1 , $ this ->currentLine );
292
304
}
293
305
}
294
306
} elseif (isset ($ values ['value ' ]) && self ::preg_match ('#^&(?P<ref>[^ ]++) *+(?P<value>.*)#u ' , $ values ['value ' ], $ matches )) {
0 commit comments