Bohr
Bohr

Reputation: 2126

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

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?

Upvotes: 156

Views: 179593

Answers (9)

Since Symfony 6.1 there is an even cleaner way - with no setup.

Instead of using container and service/parameter locator anti-pattern, you can still pass parameters to a class via its constructor, but with no need to set up a bind configuration and not only in controllers but also in any service. You just need to use an Autowire attribute.

If I re-use the sample from Tomas Votruba :

<?php declare(strict_types=1);

use Symfony\Component\DependencyInjection\Attribute\Autowire;

final class AnyService
{
    public function __construct(
        #[Autowire('%api_pass%')]
        private string $apiPass,
    
        #[Autowire('%api_user%')]
        private string $apiUser
    ) {}

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

You can find a bit more in the documentation.

Upvotes: 0

Tomas Votruba
Tomas Votruba

Reputation: 24280

Since Symfony 3.3 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...)).

Upvotes: 32

Toothgip
Toothgip

Reputation: 536

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

Upvotes: 2

Achraf JEDAY
Achraf JEDAY

Reputation: 2104

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');

Upvotes: 1

Ghazaleh Javaheri
Ghazaleh Javaheri

Reputation: 2117

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.

Upvotes: 12

Atikrant Upadhye
Atikrant Upadhye

Reputation: 195

You can also use:

$container->getParameter('api_user');

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

Upvotes: -1

mrDjouk
mrDjouk

Reputation: 381

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

Upvotes: 2

Gravitty
Gravitty

Reputation: 131

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;
}

Upvotes: 12

Vitalii Zurian
Vitalii Zurian

Reputation: 17976

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');

Upvotes: 304

Related Questions