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.