Skip to content

[DI] Environment Variable Processors not working #37426

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

Closed
peter-gribanov opened this issue Jun 26, 2020 · 3 comments
Closed

[DI] Environment Variable Processors not working #37426

peter-gribanov opened this issue Jun 26, 2020 · 3 comments

Comments

@peter-gribanov
Copy link
Contributor

peter-gribanov commented Jun 26, 2020

Symfony version(s) affected: 4.4.10

Description

The documentation says that i can use type conversion for environment variables in configuration files, but this does not work for me.

I am trying to upgrade a project from Symfony 3.4 to 4.4. Maybe i missed something.
Previously, i used an explicit conversion in the PHP file parameters.php.

How to reproduce

Reproducing Complex Bugs
https://github.com/peter-gribanov/symfony_issue_37426

My config

parameters:
    env(WEB_PROFILER): 0

web_profiler:
    toolbar: '%env(bool:WEB_PROFILER)%'
    intercept_redirects: false

framework:
    profiler:
        enabled: '%env(bool:WEB_PROFILER)%'
        collect: '%env(bool:WEB_PROFILER)%'
        only_exceptions: false

throw error

# ./bin/console
Symfony\Component\Config\Definition\Exception\InvalidTypeException^ {#12035
  -path: "web_profiler.toolbar"
  -containsHints: false
  #message: "Invalid type for path "web_profiler.toolbar". Expected boolean, but got string."
  #code: 0
  #file: "./vendor/symfony/config/Definition/BooleanNode.php"
  #line: 29
  trace: {
    ./vendor/symfony/config/Definition/BooleanNode.php:29 { …}
    ./vendor/symfony/config/Definition/BaseNode.php:534 { …}
    ./vendor/symfony/config/Definition/BaseNode.php:379 { …}
    ./vendor/symfony/config/Definition/ArrayNode.php:292 { …}
    ./vendor/symfony/config/Definition/BaseNode.php:382 { …}
    ./vendor/symfony/config/Definition/Processor.php:34 { …}
    ./vendor/symfony/config/Definition/Processor.php:50 { …}
    ./vendor/symfony/dependency-injection/Extension/Extension.php:113 { …}
    ./vendor/symfony/web-profiler-bundle/DependencyInjection/WebProfilerExtension.php:44 { …}
    ./vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php:76 { …}
    ./vendor/symfony/http-kernel/DependencyInjection/MergeExtensionConfigurationPass.php:39 { …}
    ./vendor/symfony/dependency-injection/Compiler/Compiler.php:94 { …}
    ./vendor/symfony/dependency-injection/ContainerBuilder.php:762 { …}
    ./vendor/symfony/http-kernel/Kernel.php:596 { …}
    ./vendor/symfony/http-kernel/Kernel.php:136 { …}
    ./bin/console:25 {
      › $kernel = new Kernel($env, $debug);
      › $kernel->boot();
      ›
    }
  }
}
2020-06-26T16:33:26+03:00 [critical] Uncaught Exception: Invalid type for path "web_profiler.toolbar". Expected boolean, but got string.

Possible Solution

Additional context

$ composer show symfony/*
symfony/asset                      v4.4.10 Symfony Asset Component
symfony/cache                      v4.4.10 Symfony Cache component with PSR-6, PSR-16, and tags
symfony/cache-contracts            v2.1.2  Generic abstractions related to caching
symfony/config                     v4.4.10 Symfony Config Component
symfony/console                    v4.4.10 Symfony Console Component
symfony/debug                      v4.4.10 Symfony Debug Component
symfony/debug-bundle               v4.4.10 Symfony DebugBundle
symfony/dependency-injection       v4.4.10 Symfony DependencyInjection Component
symfony/deprecation-contracts      v2.1.2  A generic function and convention to trigger deprecation notices
symfony/doctrine-bridge            v4.4.10 Symfony Doctrine Bridge
symfony/dom-crawler                v4.4.10 Symfony DomCrawler Component
symfony/dotenv                     v4.4.10 Registers environment variables from a .env file
symfony/error-handler              v4.4.10 Symfony ErrorHandler Component
symfony/event-dispatcher           v4.4.10 Symfony EventDispatcher Component
symfony/event-dispatcher-contracts v1.1.7  Generic abstractions related to dispatching event
symfony/expression-language        v4.4.10 Symfony ExpressionLanguage Component
symfony/filesystem                 v5.1.2  Symfony Filesystem Component
symfony/finder                     v5.1.2  Symfony Finder Component
symfony/flex                       v1.8.4  Composer plugin for Symfony
symfony/form                       v4.4.10 Symfony Form Component
symfony/framework-bundle           v4.4.10 Symfony FrameworkBundle
symfony/http-client                v5.1.2  Symfony HttpClient component
symfony/http-client-contracts      v2.1.2  Generic abstractions related to HTTP clients
symfony/http-foundation            v4.4.10 Symfony HttpFoundation Component
symfony/http-kernel                v4.4.10 Symfony HttpKernel Component
symfony/inflector                  v5.1.2  Symfony Inflector Component
symfony/intl                       v5.1.2  A PHP replacement layer for the C intl extension that includes addition...
symfony/mime                       v5.1.2  A library to manipulate MIME messages
symfony/monolog-bridge             v5.1.2  Symfony Monolog Bridge
symfony/monolog-bundle             v3.5.0  Symfony MonologBundle
symfony/options-resolver           v4.4.10 Symfony OptionsResolver Component
symfony/orm-pack                   v1.0.8  A pack for the Doctrine ORM
symfony/polyfill-ctype             v1.17.1 Symfony polyfill for ctype functions
symfony/polyfill-iconv             v1.17.1 Symfony polyfill for the Iconv extension
symfony/polyfill-intl-grapheme     v1.17.1 Symfony polyfill for intl's grapheme_* functions
symfony/polyfill-intl-icu          v1.17.1 Symfony polyfill for intl's ICU-related data and classes
symfony/polyfill-intl-idn          v1.17.1 Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions
symfony/polyfill-intl-normalizer   v1.17.1 Symfony polyfill for intl's Normalizer class and related functions
symfony/polyfill-mbstring          v1.17.1 Symfony polyfill for the Mbstring extension
symfony/polyfill-php70             v1.17.1 Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions
symfony/polyfill-php72             v1.17.0 Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions
symfony/polyfill-php73             v1.17.1 Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions
symfony/polyfill-php80             v1.17.1 Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions
symfony/polyfill-uuid              v1.17.1 Symfony polyfill for uuid functions
symfony/process                    v5.1.2  Symfony Process Component
symfony/profiler-pack              v1.0.4  A pack for the Symfony web profiler
symfony/property-access            v4.4.10 Symfony PropertyAccess Component
symfony/routing                    v4.4.10 Symfony Routing Component
symfony/security-acl               v3.0.4  Symfony Security Component - ACL (Access Control List)
symfony/security-bundle            v4.4.10 Symfony SecurityBundle
symfony/security-core              v4.4.10 Symfony Security Component - Core Library
symfony/security-csrf              v4.4.10 Symfony Security Component - CSRF Library
symfony/security-guard             v4.4.10 Symfony Security Component - Guard
symfony/security-http              v4.4.10 Symfony Security Component - HTTP Integration
symfony/serializer                 v4.4.10 Symfony Serializer Component
symfony/service-contracts          v2.1.2  Generic abstractions related to writing services
symfony/stopwatch                  v5.1.2  Symfony Stopwatch Component
symfony/string                     v5.1.2  Symfony String component
symfony/swiftmailer-bundle         v3.4.0  Symfony SwiftmailerBundle
symfony/templating                 v4.4.10 Symfony Templating Component
symfony/translation                v4.4.10 Symfony Translation Component
symfony/translation-contracts      v2.1.2  Generic abstractions related to translation
symfony/twig-bridge                v4.4.10 Symfony Twig Bridge
symfony/twig-bundle                v4.4.10 Symfony TwigBundle
symfony/twig-pack                  v1.0.0  A Twig pack for Symfony projects
symfony/validator                  v4.4.10 Symfony Validator Component
symfony/var-dumper                 v4.4.10 Symfony mechanism for exploring and dumping PHP variables
symfony/var-exporter               v5.1.2  A blend of var_export() + serialize() to turn any serializable data str...
symfony/web-profiler-bundle        v5.0.10 Symfony WebProfilerBundle
symfony/yaml                       v4.4.10 Symfony Yaml Component
@nicolas-grekas
Copy link
Member

There is a major difference between what you did previously in parameters.php and how %env(...)% vars work: they are read at runtime, while what you did in parameters.php was likely done once at compile time.

It is not possible to use %env(...)% vars to conditionally enable services.

I don't know why the error message tells that a string was passed (/cc @ro0NL maybe if you want to have a look). But this is not the issue you're reporting so I'm still closing.

Thanks for your understanding.

@nicolas-grekas
Copy link
Member

(Note that the error message should be fixed by #37511)

@peter-gribanov
Copy link
Contributor Author

There is a major difference between what you did previously in parameters.php and how %env(...)% vars work: they are read at runtime, while what you did in parameters.php was likely done once at compile time.

I reread the documentation. Yes, this is my mistake. Sorry. I thought that environment variables are compiled once into a container as usual parameters, but it turned out that they are parsed for each request.

It turns out that when i do not need to recognize environment variables in runtime i have to use the old approach like this:

# parameters.php
$container->setParameter('web_profiler', (bool) getenv('WEB_PROFILER'));
# web_profiler.yml
web_profiler:
    toolbar: '%web_profiler%'
    intercept_redirects: false

framework:
    profiler:
        enabled: '%web_profiler%'
        collect: '%web_profiler%'
        only_exceptions: false

It would be nice to separate environment variables into those that should be used in runtime and those that can be compiled.

nicolas-grekas added a commit that referenced this issue Jul 15, 2020
…ue prefixes for dynamic placeholder values (fancyweb)

This PR was merged into the 4.4 branch.

Discussion
----------

[DependencyInjection][Config] Use several placeholder unique prefixes for dynamic placeholder values

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | #37426
| License       | MIT
| Doc PR        |-

Currently, in Config BaseNode, we are only able to check on one dynamic placeholder unique prefix (ie one env placeholder unique prefix in our usage) to ignore the validation of config values that contain placeholder values. It isn't enough in some scenarios, we would need to be able to check on multiple prefixes.

In MergeExtensionConfigurationPass we need to not validate config values that are placeholders (they are checked later by a dedicated pass), so we set the BaseNode placeholder unique prefix for each processed extension. Because the env placeholder unique prefix depends of the bag data, if a first extension creates the env placeholder and adds a parameter to the bag, the second extension reusing the same env placeholder will generate a different env placeholder unique prefix. Therefore the validation of the value will not be skipped because the env placeholder contains the first env placeholder unique prefix while the BaseNode placeholder unique prefix is set with the second.

Another solution might be to mutate the existing env placeholders to use the new unique prefix when merging the env placeholders ? I guess it depends on which side we want to fix this (DI or Config).

cc @ro0NL

Commits
-------

3d754ad [DependencyInjection][Config] Use several placeholder unique prefixes for dynamic placeholder values
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants