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.