Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine


Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

We know there's this container concept that holds all of our services... and we can see the full list of services by running:

php bin/console debug:container

Listing Parameters

Well, it turns out that the container holds one other thing: grudges. Seriously, don't expect to pull a prank on the service container and get away with it.

Ok, what it really holds, in addition to services, is parameters. These are simple configuration values, and we can see them by running a similar command:

php bin/console debug:container --parameters

These are basically variables that you can read and reference in your code. We don't need to worry about most of these, actually. They're set by internal things and used by internal things. But there are a few that start with kernel that are pretty interesting, like kernel.project_dir, which points to the directory of our project. Yep! If you ever need a way to refer to the directory of your app, this parameter can help.

Fetching Parameters from a Controller

So... how do we use these parameters? There are two ways. First, it's not super common, but you can fetch a parameter in your controller. For example, in VinylController, let's dd($this->getParameter()) - which is a shortcut method from AbstractController - and then kernel.project_dir. We even get some nice auto-completion thanks to the Symfony PhpStorm plugin!

... lines 1 - 10
class VinylController extends AbstractController
... lines 13 - 31
public function browse(MixRepository $mixRepository, string $slug = null): Response
... lines 35 - 42

And when we try it... yep! There it is!

Referencing Parameters with %parameter%

Now... delete that. This works, but most of the time, the way you'll use parameters is by referencing them in your configuration files. And we've seen this before! Open up config/packages/twig.yaml:

default_path: '%kernel.project_dir%/templates'
... lines 3 - 7

Remember that default_path? That's referencing the kernel.project_dir parameter. When you're in any of these .yaml configuration files and you want to reference a parameter, you can use this special syntax: %, the name of the parameter, then another %.

Creating a new Parameter

Open up cache.yaml. We're setting cache.adapter to filesystem for all environments. Then, we're overriding it to be the array adapter in the dev environment only. Let's see if we can shorten this by creating a new parameter.

How do we create parameters? In any of these files, add a root key called parameters. Below that, you can just... invent a name. I'll call it cache_adapter, and set that to our value: cache.adapter.filesystem:

cache_adapter: 'cache.adapter.filesystem'
... lines 3 - 28

If you have a root framework key, Symfony will pass all of the config to FrameworkBundle. The same is true with the twig key and TwigBundle.

But parameters is special: anything under this will create a parameter.

So yea... we now have a new cache.adapter parameter... that we're not actually using yet. But we can already see it! Run:

php bin/console debug:container --parameters

Near the top... there it is - cache_adapter! To use this, down here for app, say %cache_adapter%:

cache_adapter: 'cache.adapter.filesystem'
... line 3
... lines 6 - 13
app: '%cache_adapter%'
... lines 15 - 28

That's it. Quick note: You may have noticed that sometimes I use quotes in YAML and sometimes I don't. Mostly, in YAML, you don't need to use quotes... but you always can. And if you're ever not sure if they're needed or not, better to be safe and use them.

Parameters are actually one example where quotes are required. If we didn't surround this with quotes, it would look like a special YAML syntax and throw an error.

Anyway, in the dev environment, instead of saying framework, cache, and app, all we need to do is override that parameter. I'll say parameters, then cache_adapter... and set it to cache.adapter.array:

cache_adapter: 'cache.adapter.filesystem'
... line 3
... lines 6 - 13
app: '%cache_adapter%'
... lines 15 - 23
cache_adapter: 'cache.adapter.array'

To see if that's working, spin over here and run another helper command:

php bin/console debug:config framework cache

Remember, debug:config will show you what your current configuration is under the framework key, and then the cache sub-key. And you can see here that app is set to cache.adapter.array - the resolved value for the parameter.

Let's check the value in the prod environment... just to make sure it's right there too. When you run any bin/console command, that command will execute in the same environment your app is running in. So when we ran debug:config, that ran in the dev environment.

To run the command in the prod environment, we could go over here and change APP_ENV to prod temporarily... but there's an easier way. You can override the environment when running any command by adding a flag at the end. For example:

php bin/console debug:config framework cache --env=prod

But before we try that, we always need to clear our cache first to see changes in the prod environment. Do that by running:

php bin/console cache:clear --env=prod

Now try:

php bin/console debug:config framework cache --env=prod

And... beautiful! It shows cache.adapter.filesystem. So, the container also holds parameters. This isn't a super important concept in Symfony, so, as long as you understand how they work, you're good.

Ok, let's turn back to dependency injection. We know that we can autowire services into the constructor of a service or into controller methods. But what if we need to pass something that's not autowireable? Like, what if we wanted to pass one of these parameters to a service? Let's find out how that works next.

Leave a comment!

Login or Register to join the conversation
Jim-B Avatar

Coming from Laravel, I'm a bit confused where I can put general config for my app. In Laravel I could just create a MyApp.php file in the config folder and then read it from wherever. So say I have some project-wide config in my Symfony app, where should I put it? I tried creating a app.yaml file in config/packages but when I run debug:config app it says "No extensions with configuration available for "app"".

Victor Avatar Victor | SFCASTS | Jim-B | posted 4 months ago | edited

Hey Jim,

Yeah, that config/packages/ folder is special and contains bundle-specific configs :) Try to put your config in just config/ dir, it should work well this way :)


Jim-B Avatar

Thanks for the reply Victor. Unfortunately I still get the same error, also after clearing the cache. So in the config directory I have put a file app.yaml, which looks a bit like this:

  foo: bar

Then when I run debug:config app I get the error described above. And when, in a console command, I have


I get the error "You have requested a non-existent parameter "app.foo"".


Hey Jim-B,

Wait, if you drop that app.yaml file from the config/packages/ and put into config/ - you should not have that No extensions with configuration available for "app" error anymore, as nobody will parse your file at all. And this means you would need to parse that file yourself.

But in your second example I see you just want to add some data to the config so that system knows about your data. If so, you need to add "parameters" - that's how it's called in Symfony. For this, you can open config/services.yaml and under parameters: key add your data. Then you will be able to fetch those parameters with the code you showed in the end :)


Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "knplabs/knp-time-bundle": "^1.18", // v1.19.0
        "symfony/asset": "6.1.*", // v6.1.0-RC1
        "symfony/console": "6.1.*", // v6.1.0-RC1
        "symfony/dotenv": "6.1.*", // v6.1.0-RC1
        "symfony/flex": "^2", // v2.1.8
        "symfony/framework-bundle": "6.1.*", // v6.1.0-RC1
        "symfony/http-client": "6.1.*", // v6.1.0-RC1
        "symfony/monolog-bundle": "^3.0", // v3.8.0
        "symfony/runtime": "6.1.*", // v6.1.0-RC1
        "symfony/twig-bundle": "6.1.*", // v6.1.0-RC1
        "symfony/ux-turbo": "^2.0", // v2.1.1
        "symfony/webpack-encore-bundle": "^1.13", // v1.14.1
        "symfony/yaml": "6.1.*", // v6.1.0-RC1
        "twig/extra-bundle": "^2.12|^3.0", // v3.4.0
        "twig/twig": "^2.12|^3.0" // v3.4.0
    "require-dev": {
        "symfony/debug-bundle": "6.1.*", // v6.1.0-RC1
        "symfony/maker-bundle": "^1.41", // v1.42.0
        "symfony/stopwatch": "6.1.*", // v6.1.0-RC1
        "symfony/web-profiler-bundle": "6.1.*" // v6.1.0-RC1