-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Yaml] Added support for parsing PHP constants #18626
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
HeahDude
commented
Apr 24, 2016
•
edited
Loading
edited
Q | A |
---|---|
Branch? | master |
Bug fix? | no |
New feature? | yes |
BC breaks? | no |
Deprecations? | no |
Tests pass? | yes |
Fixed tickets | ~ |
License | MIT |
Doc PR | TODO |
I was reading http://symfony.com/doc/current/components/dependency_injection/parameters.html#constants-as-parameters and felt sad about the note for yaml support. Is this PR acceptable? Does this need a flag? Or to be reversible (which does not seem doable)? There is no sense to handle such case with the dumper imho (unless it is passed as a string?? but what would be the use case?). |
I'm -1 for such horrible hacks. YAML is not a suitable format to handle metada like describing a thing is a constant. |
Usually I would agree with @hhamon and I had the same feeling when reading the headline of this PR. But on the other hand @fabpot always wanted to have the Yaml component to support the things we need for Symfony (i.e. being able to configure the framework) instead of supporting the full YAML specs. Now, this is something that is supported by other configuration formats (i.e. PHP and XML), but which isn't supported for the YAML config format. Thus, I am 👍 for closing the gap. |
@@ -562,6 +562,8 @@ private static function evaluateScalar($scalar, $flags, $references = array()) | |||
} | |||
|
|||
return; | |||
case 0 === strpos($scalar, '!php/const:'): | |||
return @constant(substr($scalar, 11)); |
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.
I think we should to throw a ParseException
here if the constant does not exist (or at least do that when the PARSE_EXCEPTION_ON_INVALID_TYPE
flag is set).
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.
I agree, I first did it because this flag looks indeed appropriate. I don't know why I've reverted it.
So I'll push it quickly :)
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.
Well, now that I think of this again, I do not think we should evaluate the flag for this. Such an error imo should never be silenced.
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.
It's not an error, it's a warning, preventing to get null
, remove the @
and the last test fails because it gets 0.0
instead of null
. That's why I silenced it (and removed the flag in the process without giving it a second thought).
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.
What I mean is that this usually indicates a mistake made by the developer when writing the YAML file.
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.
Ok I now see you answered before me, I maintain my proposal though, but I'm not against yours.
Still I would rather not add a new flag for this, the goal here is to ease configuration ; currently you need to import an xml
or a php
file while yaml
is very common (I think and always used it only).
So needing to add a flag does not seem to "keep it easy" while using PARSE_EXCEPTION_ON_INVALID_TYPE
looks more like "keep doing as usual, just pass a constant if you want".
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.
@HeahDude Well, for the configuration of services the users would not have to do that. It's the responsibility of us to set up the parser properly in the YamlFileLoader
. So we are more talking about someone who uses the parser in their own code.
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.
Understood! So I need to:
- add a flag like
PARSE_PHP_CONSTANTS
inYaml
class - either throw a
ParseException
or returnnull
when the constant does not exist
maybe usingPARSE_EXCEPTION_ON_INVALID_TYPE
- add the flag
PARSE_PHP_CONSTANTS
toYamlFileLoader
config.
Is that correct? What about point 2?
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.
I agree. And I think as you would then have to deliberately turn on the feature, throwing an exception when a constant does not exist is the right way.
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.
I'm almost there :)
Since the constant are not autoloaded (IIUC), one may expect to get null
if a constant is not defined in an environment, so I guess we can take advantage of the triggered E_WARNING
(ref http://php.net/manual/en/function.constant.php) as it will be shown as a silenced error in the profiler thanks to #16760.
Hence, I suggest we only trigger an exception when PARSE_EXCEPTION_ON_INVALID_TYPE
flag is passed.
EDIT then it could be up to the user to test null !== $constant
when no exception is thrown(?)
I already did such implementation but I've got an issue when the constant is not "inlined":
foo:
- '!php/const:PHP_INT_MAX' # does not work
bar: ['!php/const:PHP_INT_MAX'] # works
baz: { foo: '!php/const:PHP_INT_MAX' } # works
I think it comes from the Parser
as I only changed the Inline
class for now, any lead ?
Thanks.
I would be really happy to see this implemented. I prefer yaml over xml by a lot for non-public packages, but not having constants is a big limitation to yaml :( |
4f0835c
to
a58d960
Compare
3.2.0 | ||
----- | ||
|
||
* added support for PHP constants in yaml configuration files |
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.
YAML
09134dc
to
06fcb9f
Compare
Ok, comments addressed, tests are green :) I guess the failure on low depth will have to wait for master to point on 3.2. |
Supporting PHP constants would be nice but the proposed syntax |
@dunglas suggestions are welcome! It actually matches the object syntax |
Could be like float or binary |
@@ -562,6 +564,15 @@ private static function evaluateScalar($scalar, $flags, $references = array()) | |||
} | |||
|
|||
return; | |||
case 0 === strpos($scalar, '!php/const:'): | |||
if (self::$constantSupport) { | |||
return @constant(substr($scalar, 11)); |
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.
receiving null when a constant does not exist makes debugging very hard when you make a typo
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.
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.
well, IMO, we should not silence things here
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.
It would be consistent with the current XmlLoader
indeed. But null
will be returned anyway with an E_WARNING
.
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.
We shouldn't we trigger an exception when the const is not defined? Would look better to me ATM
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.
Is there a way to distinguish null
when assigned to a constant from when it's not defined?
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.
yes, using defined()
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.
no it cannot. |
Ok, so why not |
I would not change the tag name. The |
@xabbuh it makes perfectly sense but |
I'm against adding something that does not follow the YAML specification. |
If I understand correctly the spec, both proposals are valid: http://www.yaml.org/spec/1.2/spec.html#id2782728 |
@@ -22,6 +22,7 @@ | |||
use Symfony\Component\Yaml\Exception\ParseException; | |||
use Symfony\Component\Yaml\Parser as YamlParser; | |||
use Symfony\Component\ExpressionLanguage\Expression; | |||
use Symfony\Component\Yaml\Yaml; |
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.
can you please move it one line up in the yaml group?
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.
Are you sure about this? The "good way" would be to move up the Expression
line but as a CS fix it shouldn't be done in master, right?
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.
let's group yaml lines now that we can (but we don't move existing lines to reduce merge conflicts)
Comments addressed. Waiting for tests to be green, needs review, thanks! |
👍 |
@@ -366,7 +367,7 @@ protected function loadFile($file) | |||
} | |||
|
|||
try { | |||
$configuration = $this->yamlParser->parse(file_get_contents($file)); | |||
$configuration = $this->yamlParser->parse(file_get_contents($file), Yaml::PARSE_CONSTANT); | |||
} catch (ParseException $e) { |
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 Symfony\Component\Yaml\Exception\RuntimeException
might not be caught here, @xabbuh any ideas on how we should handle it?
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.
Status: needs work |
5fda13c
to
6152fb5
Compare
Updated. |
Status: Needs Review |
👍 (failures not related) |
throw new ParseException(sprintf('The constant "%s" is not defined.', $const)); | ||
} | ||
if (self::$exceptionOnInvalidType) { | ||
throw new ParseException(sprintf('The string "%s" could not be parsed as constant. Have you forgotten to pass "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar)); |
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.
[...] pass the [...]
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.
[...] be parsed as a constant.
4f861c0
to
17ec26e
Compare
Thank you @HeahDude. |
This PR was merged into the 3.2-dev branch. Discussion ---------- [Yaml] Added support for parsing PHP constants | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | ~ | License | MIT | Doc PR | TODO Commits ------- 17ec26e [DI] added support for PHP constants in yaml configuration files 02d1dea [Yaml] added support for parsing PHP constants
It's unfortunate that we did not consider it important to adhere to the YAML spec: http://www.yaml.org/spec/1.2/spec.html#tag/local/ EDIT: See #22913 😄 |