Bagaimana cara membaca dari parameter.yml di controller di symfony2?

146

Saya telah meletakkan beberapa variabel khusus di app / config / parameter.yml saya.

parameters:
    api_pass: apipass
    api_user: apiuser

Saya perlu mengakses ini dari controller saya, dan telah mencoba mengambilnya dengan

$this->get('api_user');

dari dalam file controller saya. Ketika saya mencoba ini, saya mendapatkan pesan kesalahan ini:

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

Apa cara yang benar untuk melakukan ini?

Bohr
sumber

Jawaban:

296

Dalam Symfony 2.6 dan versi yang lebih lama , untuk mendapatkan parameter di controller - Anda harus mendapatkan wadah terlebih dahulu, dan kemudian - parameter yang diperlukan.

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

Bab dokumentasi ini menjelaskannya.

Sedangkan $this->get()metode dalam pengontrol akan memuat layanan ( doc )

Di Symfony 2.7 dan versi yang lebih baru , untuk mendapatkan parameter di controller Anda bisa menggunakan yang berikut:

$this->getParameter('api_user');
Vitalii Zurian
sumber
3
Perhatikan bahwa getmetode dalam pengontrol menggunakan wadah juga, tetapi hanya bisa mendapatkan layanan dari wadah, bukan parameter. Anda perlu getParametermendapatkan parameter.
Wouter J
Ketika saya mencoba, $this->getContainer()->getParameter('api_user');saya mendapatkan kesalahan fatal: Panggil ke metode tidak terdefinisi .. Longpath .. \ Controller :: getContainer ().
Bohr
1
@ Maaf, versi berbeda dari Symfony2. Saya telah mengedit jawaban saya - cek sekarang;)
Vitalii Zurian
2
URL untuk dokumentasi sekarang symfony.com/doc/2.7/components/dependency_injection/…
SilvioQ
Symfony 2.7 dan yang lebih baru: $this->hasParameter()belum berfungsi.
Saman Mohamadi
23

The Clean Way - 2018+, Symfony 3.4+

Sejak 2017 dan Symfony 3.3 + 3.4 ada banyak cara yang lebih bersih - mudah diatur dan digunakan.

Alih-alih menggunakan container dan service / parameter locator anti-pattern, Anda bisa meneruskan parameter ke kelas melalui konstruktornya . Jangan khawatir, ini bukan pekerjaan yang menuntut waktu, melainkan pengaturan sekali & lupakan pendekatan.

Bagaimana cara mengaturnya dalam 2 langkah?

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. Apa saja 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"
    }
}

Upgrade Instan Siap!

Jika Anda menggunakan pendekatan yang lebih lama, Anda dapat mengotomatiskannya dengan Rektor .

Baca lebih banyak

Ini disebut pendekatan konstruktor melalui layanan locator .

Untuk membaca lebih lanjut tentang ini, periksa posting saya Cara Mendapatkan Parameter di Symfony Controller the Clean Way .

(Sudah diuji dan saya tetap memperbaruinya untuk versi utama Symfony baru (5, 6 ...)).

Tomáš Votruba
sumber
Cara minimalis baru tentang topik ini: tomasvotruba.cz/blog/2018/11/05/…
Tomáš Votruba
10

Saya mengirimkan contoh kepada Anda dengan swiftmailer:

parameter.yml

recipients: [email1, email2, email3]

jasa:

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

kelas layanan:

protected $recipients;

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

Di Symfony 4, Anda dapat menggunakan 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');
        // ...
    }
}

dan di app/config/services.yaml:

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

Ini bekerja untuk saya di kelas controller dan form. Rincian lebih lanjut dapat ditemukan di blog Symfony .

ghazaleh javaheri
sumber
1
Melewati seluruh parameter tas seperti melewati seluruh wadah. Masuk akal hanya dalam "jika beberapa layanan tertentu membutuhkan banyak parameter wadah" (dikutip dari pos)
Tomáš Votruba
Jadi, apakah maksud Anda melewati seluruh parameter menyebabkan masalah dalam kinerja?
ghazaleh javaheri
Itu salah satu alasan, tetapi sebagian besar untuk keterbacaan. Jika saya melihat nama parameter, $meetupApiKeysaya tahu apa yang diharapkan sedikit lebih baik daripada di$parameterBag
Tomáš Votruba
0

Dalam Symfony 4.3.1 saya menggunakan ini:

layanan.yaml

HTTP_USERNAME: 'admin'
HTTP_PASSWORD: 'password123'

FrontController.php

$username = $this->container->getParameter('HTTP_USERNAME');
$password = $this->container->getParameter('HTTP_PASSWORD');
Achraf JEDAY
sumber
Tidak bekerja di 4.8. Apakah Anda yakin itu bekerja suatu hari nanti?
Ricardo Martins
Saya benar-benar lupa tentang ini, tetapi ya itu mungkin berhasil karena saya memposting hanya barang yang diuji!
Achraf JEDAY
1
Maaf, Acharaf. Saya tidak tahu, tetapi tidak bekerja di controller saya. Di dalam controller Anda, Anda dapat memanggil getParameter secara langsung, tanpa DI. Yaitu: $this->getParameter('foo'). Itulah yang saya lakukan untuk membuatnya bekerja di SF 4.8.
Ricardo Martins