Come posso leggere da parameter.yml in un controller in symfony2?


146

Ho inserito un paio di variabili personalizzate nella mia app / config / parametri.yml.

parameters:
    api_pass: apipass
    api_user: apiuser

Devo accedere a questi dal mio controller e ho cercato di recuperarli

$this->get('api_user');

dall'interno del mio file controller. Quando provo questo, ricevo questo messaggio di errore:

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

Qual è il modo corretto per farlo?

Risposte:


296

In Symfony 2.6 e versioni precedenti , per ottenere un parametro in un controller - dovresti prima ottenere il contenitore e poi - il parametro necessario.

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

Questo capitolo della documentazione lo spiega.

Mentre il $this->get()metodo in un controller caricherà un servizio ( doc )

In Symfony 2.7 e versioni successive , per ottenere un parametro in un controller è possibile usare quanto segue:

$this->getParameter('api_user');

3
Si noti che il getmetodo nel controller utilizza anche il contenitore, ma può ottenere solo servizi da un contenitore, non parametri. Devi getParameterottenere parametri.
Wouter J,

Quando provo $this->getContainer()->getParameter('api_user');ottengo un errore irreversibile: chiama il metodo indefinito ..Longpath .. \ Controller :: getContainer ().
Bohr,

1
@Bohr scusa, versione diversa di Symfony2. Ho modificato la mia risposta - controllala ora;)
Vitalii Zurian,


Symfony 2.7 e versioni successive: $this->hasParameter()non funziona ancora.
Saman Mohamadi,

23

The Clean Way - 2018+, Symfony 3.4+

Dal 2017 e Symfony 3.3 + 3.4 esiste un modo molto più pulito: facile da configurare e utilizzare.

Invece di usare l'anti-pattern contenitore e servizio / localizzatore parametri, è possibile passare i parametri alla classe tramite il suo costruttore . Non ti preoccupare, non è un lavoro che richiede tempo, ma piuttosto impostare una volta e dimenticare l' approccio.

Come configurarlo in 2 passaggi?

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

Aggiornamento istantaneo pronto!

Se usi un approccio precedente, puoi automatizzarlo con Rector .

Leggi di più

Questo si chiama iniezione del costruttore sul localizzatore di servizi all'approccio di .

Per saperne di più su questo, controlla il mio post Come ottenere parametri in Symfony Controller in modo pulito .

(È testato e lo tengo aggiornato per la nuova versione principale di Symfony (5, 6 ...)).


Nuovo modo minimalista su questo argomento: tomasvotruba.cz/blog/2018/11/05/…
Tomáš Votruba

10

Ti invio un esempio con swiftmailer:

parameters.yml

recipients: [email1, email2, email3]

Servizi:

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

la classe del servizio:

protected $recipients;

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

8

In Symfony 4, puoi usare 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');
        // ...
    }
}

e in app/config/services.yaml:

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

Funziona per me in entrambe le classi controller e form. Maggiori dettagli sono disponibili nel blog di Symfony .


1
Passare interi parametri è come passare un intero contenitore. Ha senso solo in "se un determinato servizio necessita di molti parametri container" (citato dalla posta)
Tomáš Votruba

quindi, vuoi dire che passare l'intero parametro causa problemi nelle prestazioni?
ghazaleh javaheri,

Questo è uno dei motivi, ma soprattutto per la leggibilità. Se vedo il nome del parametro $meetupApiKeyso cosa aspettarmi un po 'meglio che in$parameterBag
Tomáš Votruba


0

In Symfony 4.3.1 Uso questo:

services.yaml

HTTP_USERNAME: 'admin'
HTTP_PASSWORD: 'password123'

FrontController.php

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

Non funziona in 4.8. Sei sicuro che abbia funzionato un giorno?
Ricardo Martins,

Me ne sono davvero dimenticato, ma sì, probabilmente ha funzionato perché invio solo materiale testato!
Achraf JEDAY

1
Scusa, Acharaf. Non lo so, ma non ha funzionato nel mio controller. All'interno del controller è possibile chiamare direttamente getParameter, senza DI. Vale a dire: $this->getParameter('foo'). Questo è quello che ho fatto per farlo funzionare in SF 4.8.
Ricardo Martins,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.