Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[DI] Allow processing env vars#23901

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
fabpot merged 1 commit intosymfony:3.4fromnicolas-grekas:env-provider
Sep 7, 2017

Conversation

@nicolas-grekas
Copy link
Member

@nicolas-grekasnicolas-grekas commentedAug 16, 2017
edited
Loading

QA
Branch?3.4
Bug fix?no
New feature?yes
BC breaks?no
Deprecations?no
Tests pass?yes
Fixed ticketssee description
LicenseMIT
Doc PR-

This PR is an updated version of#20276(it embeds#23899 for now.)

It superscedes/closes:

#22151 is another story, so not fixed here.

The way it works is via%env(foo:BAR)% prefixes, where "foo" can be bound to any services you'd like.
By default, the following prefixes are supported:

  • bool,int,float,string,base64
  • const (for referencing PHP constants)
  • json (supporting only jsonarrays for type predictability)
  • file (eg for access to secrets stored in files.)
  • resolve (for processing parameters inside env vars.)

New prefixes can be added by implementing the newEnvProviderInterface, and tagging withcontainer.env_provider (seeRot13EnvProvider in tests.)

Prefixes can be combined to chain processing, eg.
%env(json:base64:file:FOO)% will be roughly equivalent to
json_decode(base64_decode(file_get_content(getenv('FOO')))).

pyrech, mente, nfabre, Pierstoval, DavidBadura, daFish, teohhanhui, JarJak, jrysig, sadok-f, and 10 more reacted with thumbs up emojichalasr, 20uf, sstok, pyrech, Pierstoval, ro0NL, 1ed, yceruto, ogizanagi, gedimin45, and 17 more reacted with hooray emojimnapoli reacted with confused emojiogizanagi, sstok, Pierstoval, yceruto, dkarlovi, DavidBadura, teohhanhui, JarJak, sadok-f, Luitame, and pamil reacted with heart emoji
@nicolas-grekasnicolas-grekas added this to the3.4 milestoneAug 16, 2017
@nicolas-grekasnicolas-grekas changed the title[DI] Allow processing env vars - handles int/float/file/array/base64 + "container.env_provider"-tagged services[DI] Allow processing env vars - handles int/float/file/json/base64 + "container.env_provider"-tagged servicesAug 16, 2017
@marfillaster
Copy link
Contributor

👍 I totally approve this solution. The chained processing is just genius.

*
* @throws RuntimeException on error
*/
publicfunctiongetEnv($prefix,$name,\Closure$getEnv);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

preferably the namespace parsing happens inContainer::getEnv no? Basically you need to do the same check each time implementing it. What aboutgetEnv($prefix, $name, $value, \Closure $getEnv = null)?

Copy link
MemberAuthor

@nicolas-grekasnicolas-grekasAug 16, 2017
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

namespace parsing already happens inContainer::getEnv.
What you see here is forwarding, which is something not all providers are required to do.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

never mind, thats simply$value = $getEnv($name) currently. Basically the trick is to not forgetreturn $getEnv($name) for defaulting.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

and i missed your comment in between.. but you're right the current implem is fine.

if (true !==$format) {
$resolved =sprintf($format,$env);
}elseif ($placeholder ===$resolved =$bag->escapeValue($this->getEnv($env))) {
$resolved =$bag->all()[strtolower("env($env)")];
Copy link
Member

@ycerutoycerutoAug 16, 2017
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Can we fix#23527 (comment) somehow?

Copy link
MemberAuthor

@nicolas-grekasnicolas-grekasAug 16, 2017
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@yceruto here we are, with a newresolve handler to the rescue.

yceruto reacted with hooray emoji
@mnapoli
Copy link
Contributor

mnapoli commentedAug 16, 2017
edited
Loading

Is%env(json:base64:file:FOO)% really more understandable thanjson_decode(base64_decode(file_get_content(getenv('FOO'))))?
This is yet another custom syntax that Symfony users will need to learn, whereas plain old PHP would do the same with a few more characters. Maybe these kind of problems could be solved with#22407/#23834 and allowing to write some entries as PHP closures? This is a more complex solution though ("easy to say"), but the end result would be maybe much simpler for users?

@nicolas-grekas
Copy link
MemberAuthor

nicolas-grekas commentedAug 16, 2017
edited
Loading

@mnapoli I think you're forgetting about how things work. Despite your claim in#22407, a PHP DSL would not help at all reading from the env. The reason is compilation of the container. The DSL is read once, at compile time.%env(FOO)% is the syntax that we already use to be able to declare that intention of compiling down to dynamic calls. The namespaced env vars only build on top of this to add more processing capabilities to env, nothing more. It's not only about syntactic sugar.

@mnapoli
Copy link
Contributor

👍 sorry :)

sstok reacted with thumbs up emoji

if (isset($attr['prefix'])) {
$providers[$attr['prefix']] =newReference($id);
}elseif (!$r =$container->getReflectionClass($class =$container->getDefinition($id)->getClass())) {
thrownewInvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.',$class,$id));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Does this mean that the service class existence is not resolved at compile time?

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yes, as done commonly in other passes: when it's not required at compile time, we usually don't validate that kind of things.

@nicolas-grekasnicolas-grekas changed the title[DI] Allow processing env vars - handles int/float/file/json/base64 + "container.env_provider"-tagged services[DI] Allow processing env varsAug 16, 2017
100 =>array(
$resolveClassPass =newResolveClassPass(),
newResolveInstanceofConditionalsPass(),
newRegisterEnvProvidersPass(),
Copy link
MemberAuthor

@nicolas-grekasnicolas-grekasAug 16, 2017
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

registered before optimization passes so that env values can be used at compile time (typically using$container->resolveEnvPlaceholders().) This makes env providers a bit less flexible (they can't easily be manipulated by DI extensions) but that's consistent with the provided feature to me (env vars should be light to fetch.)

sstok reacted with thumbs up emoji
@Pierstoval
Copy link
Contributor

I cannot agree more on this PR 👍

@ro0NL
Copy link
Contributor

ro0NL commentedAug 17, 2017
edited
Loading

Thestr_ireplace seems to trigger an unexpectedArray to string conversion

$_ENV['REAL'] ='{"real":true}';$c =newContainerBuilder();$c->setParameter('json_real','%env(json:REAL)%');$c->register('foo','stdClass')->setProperties(array('json_real' =>'%json_real%',));$c->compile(true);

Somehow real and default envs get mixed up, probably due reference generation in EnvBag::get()

$_ENV['REAL'] ='runtime';$c =newContainerBuilder();$c->setParameter('env(REAL)','compiletime');$c->setParameter('real','%env(REAL)%');$c->register('teatime','stdClass')->setProperties(array('real' =>'%real%','real_inline' =>'%env(REAL)%',));$c->compile(true);dump($c->get('teatime'));
{#136  +"real": "runtime"  +"real_inline": "compiletime"}

This looks bad 🤔


What im worried about is the current default strategy. With this feature things may work unexpected due the exact lookup.setParameter('env(REAL)', ...) will not be used if combined with any prefix, you need to expose all variants :(

Also related; if in above example you leave out the default ("compiletime"); you'll get

The service "teatime" has a dependency on a non-existent parameter "env(real)"

Yet we did a real lookup already.. so what's the deal here?


Otherwise it seems to work just great :)

@nicolas-grekas
Copy link
MemberAuthor

@ro0NL thanks for the detailed report. Good news, both (the 3 in fact) your examples apply to 3.3 also, which means you found bugs. Nothing related to this PR specifically. Those happen only incompile(true) mode, which I'm going to fix in another PR on 3.3.

@kbond
Copy link
Member

What is the reason for nobool prefix?

@nicolas-grekas
Copy link
MemberAuthor

@kbond no reason, fixed.
Now with a newconst filter also.

@nicolas-grekasnicolas-grekasforce-pushed theenv-provider branch 5 times, most recently from26c28eb to019a582CompareSeptember 6, 2017 21:02
useSymfony\Component\DependencyInjection\ContainerBuilder;
useSymfony\Component\DependencyInjection\ContainerInterface;
useSymfony\Component\DependencyInjection\Definition;
useSymfony\Component\DependencyInjection\EnvProviderInterface;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Should beEnvVarProcessorInterface (same below)

$container->registerForAutoconfiguration(ResourceCheckerInterface::class)
->addTag('config_cache.resource_checker');
$container->registerForAutoconfiguration(EnvProviderInterface::class)
->addTag('container.env_provider');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

should be renamed as well

@fabpot
Copy link
Member

Still someprovider usages (like variable names for instance).

@fabpot
Copy link
Member

Thank you@nicolas-grekas.

ro0NL reacted with hooray emojiro0NL and shouze reacted with heart emoji

@fabpotfabpot merged commit1f92e45 intosymfony:3.4Sep 7, 2017
fabpot added a commit that referenced this pull requestSep 7, 2017
This PR was merged into the 3.4 branch.Discussion----------[DI] Allow processing env vars| Q             | A| ------------- | ---| Branch?       | 3.4| Bug fix?      | no| New feature?  | yes| BC breaks?    | no| Deprecations? | no| Tests pass?   | yes| Fixed tickets | see description| License       | MIT| Doc PR        | -This PR is an updated version of#20276 ~~(it embeds#23899 for now.)~~It superscedes/closes:- [DI] Add support for secrets#23621 ping@dunglas- Runtime container parameter not found event filter#23669 ping@marfillaster- [DependencyInjection] [DX] Support for JSON string environment variables#23823 ping@Pierstoval- add support for composite environment variables#17689 ping@greg0ire- [DI] ENV parameters at runtime with PHP 7 strict types not working properly#20434 ping@sandrokeil- Issue when using a SQLite database and the DATABASE_URL env var#23527 ping@javiereguiluz#22151 is another story, so not fixed here.The way it works is via `%env(foo:BAR)%` prefixes, where "foo" can be bound to any services you'd like.By default, the following prefixes are supported:- `bool`, `int`, `float`, `string`, `base64`- `const` (for referencing PHP constants)- `json` (supporting only json **arrays** for type predictability)- `file` (eg for access to secrets stored in files.)- `resolve` (for processing parameters inside env vars.)New prefixes can be added by implementing the new `EnvProviderInterface`, and tagging with `container.env_provider` (see `Rot13EnvProvider` in tests.)Prefixes can be combined to chain processing, eg.`%env(json:base64:file:FOO)%` will be roughly equivalent to`json_decode(base64_decode(file_get_content(getenv('FOO'))))`.Commits-------1f92e45 [DI] Allow processing env vars
@nicolas-grekasnicolas-grekas deleted the env-provider branchSeptember 10, 2017 16:11
@sroze
Copy link
Contributor

Great job@nicolas-grekas 👏

This was referencedOct 18, 2017
sayjun0505 added a commit to sayjun0505/sym_proj that referenced this pull requestApr 16, 2023
…ameter (yceruto)This PR was merged into the master branch.Discussion----------Workaround to use DATABASE_URL with %kernel.project_dir% parameterSetting `DATABASE_URL=sqlite:///var/data/blog.sqlite` as default, causes this known error through `index.php`:```An exception occurred in driver: SQLSTATE[HY000] [14] unable to open database file```So the right relative path in this case should be `sqlite:///../var/data/blog.sqlite` BUT then it wouldn't work for `bin/console` entries. Then, relative paths shouldn't be the right way but absolute paths.The right thing is that soon (in 3.4 & 4.0) we can use environment variables with configuration parameterssymfony/symfony#23901, so the final configuration would be the one proposed. For now a workaround to make both scenarios work `index.php` and `bin/console`.Commits-------e45b5d5 Workaround to use DATABASE_URL with %kernel.project_dir% parameter
spider-yamet added a commit to spider-yamet/sym_proj that referenced this pull requestApr 16, 2023
…ameter (yceruto)This PR was merged into the master branch.Discussion----------Workaround to use DATABASE_URL with %kernel.project_dir% parameterSetting `DATABASE_URL=sqlite:///var/data/blog.sqlite` as default, causes this known error through `index.php`:```An exception occurred in driver: SQLSTATE[HY000] [14] unable to open database file```So the right relative path in this case should be `sqlite:///../var/data/blog.sqlite` BUT then it wouldn't work for `bin/console` entries. Then, relative paths shouldn't be the right way but absolute paths.The right thing is that soon (in 3.4 & 4.0) we can use environment variables with configuration parameterssymfony/symfony#23901, so the final configuration would be the one proposed. For now a workaround to make both scenarios work `index.php` and `bin/console`.Commits-------e45b5d5 Workaround to use DATABASE_URL with %kernel.project_dir% parameter
frederickboyd pushed a commit to frederickboyd/frederickboyd that referenced this pull requestMay 25, 2025
…ameter (yceruto)This PR was merged into the master branch.Discussion----------Workaround to use DATABASE_URL with %kernel.project_dir% parameterSetting `DATABASE_URL=sqlite:///var/data/blog.sqlite` as default, causes this known error through `index.php`:```An exception occurred in driver: SQLSTATE[HY000] [14] unable to open database file```So the right relative path in this case should be `sqlite:///../var/data/blog.sqlite` BUT then it wouldn't work for `bin/console` entries. Then, relative paths shouldn't be the right way but absolute paths.The right thing is that soon (in 3.4 & 4.0) we can use environment variables with configuration parameterssymfony/symfony#23901, so the final configuration would be the one proposed. For now a workaround to make both scenarios work `index.php` and `bin/console`.Commits-------e45b5d5 Workaround to use DATABASE_URL with %kernel.project_dir% parameter
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@fabpotfabpotfabpot requested changes

@ycerutoycerutoyceruto left review comments

@dunglasdunglasdunglas approved these changes

@chalasrchalasrchalasr approved these changes

+3 more reviewers

@TaluuTaluuTaluu left review comments

@PierstovalPierstovalPierstoval left review comments

@ro0NLro0NLro0NL approved these changes

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

3.4

Development

Successfully merging this pull request may close these issues.

14 participants

@nicolas-grekas@marfillaster@mnapoli@Pierstoval@ro0NL@kbond@stof@fabpot@sroze@dunglas@Taluu@yceruto@chalasr@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp