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?

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

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


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 ...)).


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

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 .


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

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.