-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Yaml] parse merge keys with PARSE_OBJECT_FOR_MAP flag #24189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
xabbuh
commented
Sep 13, 2017
•
edited
Loading
edited
Q | A |
---|---|
Branch? | 3.3 |
Bug fix? | yes |
New feature? | no |
BC breaks? | no |
Deprecations? | no |
Tests pass? | yes |
Fixed tickets | #24133 |
License | MIT |
Doc PR |
You use same kind of foreach loops I removed via #21756 Please consider using union operator again. It reduces big chunk of unnecessary verbosity and you get NULL handling for free. Example of usage in your patch: @@ -257,14 +257,8 @@
$refValue = $this->refs[$refName];
- if (is_array($refValue)) {
- $data += $refValue; // array union
- } elseif ((bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags) && $refValue instanceof \stdClass) {
- foreach ($refValue as $refValueKey => $refValueValue) {
- if (!isset($data[$refValueKey])) {
- $data[$refValueKey] = $refValueValue;
- }
- }
+ if (is_array($refValue) || (bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags) && $refValue instanceof \stdClass) {
+ $data += (array) $refValue; // array union
} else {
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}
@@ -294,11 +288,7 @@
$data += $parsed; // array union
}
} elseif ((bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags) && $parsed instanceof \stdClass) {
- foreach ($parsed as $parsedKey => $parsedValue) {
- if (!isset($data[$parsedKey])) {
- $data[$parsedKey] = $parsedValue;
- }
- }
+ $data += (array) $parsed;
} else {
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
} |
ping @symfony/deciders :) |
@xabbuh Just tried it out, it seems to fix it for #24133 code but not for #23587. <?php
require __DIR__ .'/vendor/autoload.php';
use Symfony\Component\Yaml\Parser;
use Symfony\Component\Yaml\Yaml;
$yaml = <<<YAML
root:
mergekeyrefdef:
a: foo
<<: &quux
b: bar
c: baz
mergekeyderef:
d: quux
<<: *quux
YAML;
$arr = (new Parser())->parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP); |
@@ -249,14 +249,18 @@ private function doParse($value, $flags) | |||
if ('<<' === $key) { | |||
$mergeNode = true; | |||
$allowOverwrite = true; | |||
if (isset($values['value']) && 0 === strpos($values['value'], '*')) { | |||
if (isset($values['value']) && isset($values['value'][0]) && '*' === $values['value'][0]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the first isset
can be removed, as it is covered by the second one.
$refName = substr(rtrim($values['value']), 1); | ||
if (!array_key_exists($refName, $this->refs)) { | ||
throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine); | ||
} | ||
|
||
$refValue = $this->refs[$refName]; | ||
|
||
if ((bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags) && $refValue instanceof \stdClass) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the explicit bool
cast is useless (&&
will trigger it too)
Thank you @xabbuh. |
…bbuh) This PR was merged into the 3.3 branch. Discussion ---------- [Yaml] parse merge keys with PARSE_OBJECT_FOR_MAP flag | Q | A | ------------- | --- | Branch? | 3.3 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #24133 | License | MIT | Doc PR | Commits ------- 534eaed parse merge keys with PARSE_OBJECT_FOR_MAP flag