How do I read from parameters.yml in a controller in symfony2?
Asked Answered
L

8

156

I have put a couple of custom variables in my app/config/parameters.yml.

parameters:
    api_pass: apipass
    api_user: apiuser

I need to access these from my controller, and have tried to fetch them with

$this->get('api_user');

from within my controller file. When I try this, I get this error message:

You have requested a non-existent service "api_user".

What is the correct way to do this?

Lowery answered 16/12, 2012 at 12:23 Comment(0)
L
304

In Symfony 2.6 and older versions, to get a parameter in a controller - you should get the container first, and then - the needed parameter.

$this->container->getParameter('api_user');

This documentation chapter explains it.

While $this->get() method in a controller will load a service (doc)

In Symfony 2.7 and newer versions, to get a parameter in a controller you can use the following:

$this->getParameter('api_user');
Lemberg answered 16/12, 2012 at 12:26 Comment(6)
Note that the get method in the controller uses the container too, but it can only get services from a container, not parameters. You need getParameter to get parameters.Implead
When I try $this->getContainer()->getParameter('api_user'); I get Fatal error: Call to undefined method ..Longpath..\Controller::getContainer().Lowery
@Lowery sorry, different version of Symfony2. I've edited my answer - check it now ;)Lemberg
The URL for documentation is now symfony.com/doc/2.7/components/dependency_injection/…Boadicea
Symfony 2.7 and newer: $this->hasParameter() not working yet.Centric
You can upgrade this instantly with Rector now: github.com/rectorphp/rector/pull/333Juicy
J
32

The Clean Way - 2018+, Symfony 3.4+

Since 2017 and Symfony 3.3 + 3.4 there is much cleaner way - easy to setup and use.

Instead of using container and service/parameter locator anti-pattern, you can pass parameters to class via it's constructor. Don't worry, it's not time-demanding work, but rather setup once & forget approach.

How to set it up in 2 steps?

1. app/config/services.yml

# config.yml

# config.yml
parameters:
    api_pass: 'secret_password'
    api_user: 'my_name'

services:
    _defaults:
        autowire: true
        bind:
            $apiPass: '%api_pass%'
            $apiUser: '%api_user%'

    App\:
        resource: ..

2. Any Controller

<?php declare(strict_types=1);

final class ApiController extends SymfonyController
{
    /**
     * @var string 
     */
    private $apiPass;

    /**
     * @var string
     */
    private $apiUser;

    public function __construct(string $apiPass, string $apiUser)
    {
        $this->apiPass = $apiPass;
        $this->apiUser = $apiUser;
    }

    public function registerAction(): void
    {
        var_dump($this->apiPass); // "secret_password"
        var_dump($this->apiUser); // "my_name"
    }
}

Instant Upgrade Ready!

In case you use older approach, you can automate it with Rector.

Read More

This is called constructor injection over services locator approach.

To read more about this, check my post How to Get Parameter in Symfony Controller the Clean Way.

(It's tested and I keep it updated for new Symfony major version (5, 6...)).

Juicy answered 21/1, 2018 at 20:51 Comment(1)
New minimalistic way on this topic: tomasvotruba.cz/blog/2018/11/05/…Juicy
M
12

I send you an example with swiftmailer:

parameters.yml

recipients: [email1, email2, email3]

services:

your_service_name:
        class: your_namespace
        arguments: ["%recipients%"]

the class of the service:

protected $recipients;

public function __construct($recipients)
{
    $this->recipients = $recipients;
}
Marmot answered 31/3, 2016 at 8:28 Comment(0)
P
12

In Symfony 4, you can use the ParameterBagInterface:

use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

class MessageGenerator
{
    private $params;

    public function __construct(ParameterBagInterface $params)
    {
        $this->params = $params;
    }

    public function someMethod()
    {
        $parameterValue = $this->params->get('parameter_name');
        // ...
    }
}

and in app/config/services.yaml:

parameters:
    locale: 'en'
    dir: '%kernel.project_dir%'

It works for me in both controller and form classes. More details can be found in the Symfony blog.

Paphos answered 5/9, 2018 at 12:44 Comment(3)
Passing whole parameters bag is like passing a whole container. It makes sense only in "if some particular service needs lots of container parameters" (quoted from the post)Juicy
so ,are you mean passing whole parameter cause problem in performance?Paphos
That's one of reasons, but mostly for readability. If I see parameter name $meetupApiKey I know what to expect slightly better than in $parameterBagJuicy
S
2

You can use:

public function indexAction()
{
   dump( $this->getParameter('api_user'));
}

For more information I recommend you read the doc :

http://symfony.com/doc/2.8/service_container/parameters.html

Senecal answered 9/3, 2017 at 10:13 Comment(0)
E
2

In Symfony 5 when your Controller extends AbstractController you can use :

$projectDir = $this->getParameter('kernel.project_dir');

See https://symfony.com/doc/current/configuration.html#accessing-configuration-parameters for more info

Emboly answered 15/4, 2021 at 14:15 Comment(0)
C
1

In Symfony 4.3.1 I use this:

services.yaml

HTTP_USERNAME: 'admin'
HTTP_PASSWORD: 'password123'

FrontController.php

$username = $this->container->getParameter('HTTP_USERNAME');
$password = $this->container->getParameter('HTTP_PASSWORD');
Condyloma answered 3/7, 2019 at 9:34 Comment(3)
Doesn't work in 4.8. Are you sure it worked someday?Euphrates
I really forgot about this but yes it probably worked cause I post only tested stuff!Condyloma
Sorry, Acharaf. I don't know, but didn't work in my controller. Inside your controller you can call getParameter directly, with no DI. I.e.: $this->getParameter('foo'). That's what I did to make it work in SF 4.8.Euphrates
L
-1

You can also use:

$container->getParameter('api_user');

Visit http://symfony.com/doc/current/service_container/parameters.html

Lister answered 8/12, 2016 at 12:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.