¿Cómo leo desde los parámetros.yml en un controlador en Symfony2?


146

He puesto un par de variables personalizadas en mi aplicación / config / parameters.yml.

parameters:
    api_pass: apipass
    api_user: apiuser

Necesito acceder a estos desde mi controlador, y he intentado buscarlos con

$this->get('api_user');

desde mi archivo controlador. Cuando intento esto, recibo este mensaje de error:

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

¿Cuál es la forma correcta de hacer esto?

Respuestas:


296

En Symfony 2.6 y versiones anteriores , para obtener un parámetro en un controlador, primero debe obtener el contenedor y luego el parámetro necesario.

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

Este capítulo de documentación lo explica.

Mientras que el $this->get()método en un controlador cargará un servicio ( doc )

En Symfony 2.7 y versiones más recientes , para obtener un parámetro en un controlador, puede usar lo siguiente:

$this->getParameter('api_user');

3
Tenga en cuenta que el getmétodo en el controlador también usa el contenedor, pero solo puede obtener servicios de un contenedor, no parámetros. Necesitas getParameterobtener parámetros.
— Wouter J

Cuando lo intento $this->getContainer()->getParameter('api_user');me sale un error grave: Llame al método indefinido .. Longpath .. \ Controller :: getContainer ().
— Bohr

1
@Bohr lo siento, una versión diferente de Symfony2. He editado mi respuesta, compruébalo ahora;)
— Vitalii Zurian

2
La URL para la documentación ahora es symfony.com/doc/2.7/components/dependency_injection/…
— SilvioQ

Symfony 2.7 y más reciente: $this->hasParameter()aún no funciona.
— Saman Mohamadi

23

The Clean Way - 2018+, Symfony 3.4+

Desde 2017 y Symfony 3.3 + 3.4 hay una forma mucho más limpia: fácil de configurar y usar.

En lugar de utilizar el antipatrón de contenedor y servicio / localizador de parámetros, puede pasar parámetros a la clase a través de su constructor . No se preocupe, no es un trabajo que requiera mucho tiempo, sino más bien configurar una vez y olvidar el enfoque.

¿Cómo configurarlo en 2 pasos?

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. Cualquiera 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"
    }
}

¡Actualización instantánea lista!

En caso de que use un enfoque anterior, puede automatizarlo con Rector .

Lee mas

Esto se llama inyección de constructor sobre el enfoque del localizador de servicios .

Para leer más sobre esto, consulte mi publicación Cómo obtener el parámetro en Symfony Controller the Clean Way .

(Está probado y lo mantengo actualizado para la nueva versión principal de Symfony (5, 6 ...)).


Nueva forma minimalista sobre este tema: tomasvotruba.cz/blog/2018/11/05/…
— Tomáš Votruba

10

Te envío un ejemplo con swiftmailer:

parámetros.yml

recipients: [email1, email2, email3]

servicios:

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

la clase del servicio:

protected $recipients;

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

8

En Symfony 4, puedes usar 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');
        // ...
    }
}

y en app/config/services.yaml:

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

A mí me funciona tanto en el controlador como en las clases de formulario. Se pueden encontrar más detalles en el blog de Symfony .


1
Pasar una bolsa de parámetros completa es como pasar un contenedor completo. Tiene sentido solo en "si algún servicio en particular necesita muchos parámetros de contenedor" (citado de la publicación)
— Tomáš Votruba

Entonces, ¿te refieres a que pasar todo el parámetro causa un problema en el rendimiento?
— ghazaleh javaheri

Esa es una de las razones, pero principalmente por la legibilidad. Si veo a nombre del parámetro $meetupApiKeyque sé qué esperar un poco mejor que en$parameterBag
— Tomáš Votruba


0

En Symfony 4.3.1 uso esto:

services.yaml

HTTP_USERNAME: 'admin'
HTTP_PASSWORD: 'password123'

FrontController.php

$username = $this->container->getParameter('HTTP_USERNAME');
$password = $this->container->getParameter('HTTP_PASSWORD');

No funciona en 4.8. ¿Estás seguro de que funcionó algún día?
— Ricardo Martins

Realmente me olvidé de esto, pero sí, probablemente funcionó porque publiqué solo cosas probadas.
— Achraf JEDAY

1
Lo siento, Acharaf. No lo sé, pero no funcionó en mi controlador. Dentro de su controlador puede llamar a getParameter directamente, sin DI. Es decir: $this->getParameter('foo'). Eso es lo que hice para que funcione en SF 4.8.
— Ricardo Martins

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.