ฉันจะอ่านจาก parameters.yml ในคอนโทรลเลอร์ใน symfony2 ได้อย่างไร


146

ฉันได้ใส่ตัวแปรที่กำหนดเองสองสามตัวใน app / config / parameters.yml ของฉัน

parameters:
    api_pass: apipass
    api_user: apiuser

ฉันต้องการเข้าถึงสิ่งเหล่านี้จากคอนโทรลเลอร์ของฉันและพยายามดึงมันมาด้วย

$this->get('api_user');

จากภายในไฟล์ควบคุมของฉัน เมื่อฉันลองทำสิ่งนี้ฉันจะได้รับข้อความแสดงข้อผิดพลาดนี้:

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

วิธีที่ถูกต้องในการทำเช่นนี้คืออะไร?

คำตอบ:


296

ในSymfony 2.6 และเวอร์ชันที่เก่ากว่าเพื่อรับพารามิเตอร์ในคอนโทรลเลอร์ - คุณควรรับคอนเทนเนอร์ก่อนแล้วจึง - พารามิเตอร์ที่จำเป็น

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

นี้บทเอกสารอธิบายได้

ในขณะที่$this->get()วิธีการในตัวควบคุมจะโหลดบริการ ( doc )

ในSymfony 2.7 และเวอร์ชันที่ใหม่กว่าเพื่อรับพารามิเตอร์ในคอนโทรลเลอร์คุณสามารถใช้สิ่งต่อไปนี้:

$this->getParameter('api_user');

3
โปรดทราบว่าgetวิธีการในคอนโทรลเลอร์ใช้คอนเทนเนอร์ด้วย แต่สามารถรับบริการได้จากคอนเทนเนอร์เท่านั้นไม่ใช่พารามิเตอร์ คุณต้องgetParameterรับพารามิเตอร์
Wouter J

เมื่อฉันลอง$this->getContainer()->getParameter('api_user');ฉันพบข้อผิดพลาดร้ายแรง: Call to undefined method .. Longpath .. \ Controller :: getContainer ()
Bohr

1
@Bohr ขออภัย Symfony2 เวอร์ชันอื่น ฉันได้แก้ไขคำตอบของฉัน - ตรวจสอบตอนนี้;)
Vitalii Zurian

2
ตอนนี้ URL สำหรับเอกสารประกอบคือsymfony.com/doc/2.7/components/dependency_inject/ …
SilvioQ

Symfony 2.7 และใหม่กว่า: $this->hasParameter()ยังไม่ทำงาน
Saman Mohamadi

23

The Clean Way - 2018+, Symfony 3.4+

ตั้งแต่ปี 2560 และ Symfony 3.3 + 3.4มีวิธีที่สะอาดกว่ามาก - ติดตั้งและใช้งานง่าย

แทนการใช้ภาชนะบรรจุและการบริการ / พารามิเตอร์ระบุตำแหน่งต่อต้านรูปแบบที่คุณสามารถส่งผ่านพารามิเตอร์ในชั้นเรียนผ่านมันคอนสตรัค ไม่ต้องกังวลมันไม่ใช่งานที่ต้องใช้เวลา แต่ต้องติดตั้งเพียงครั้งเดียวและลืมวิธีการ

วิธีการตั้งค่าใน 2 ขั้นตอน?

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. ใด ๆ 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"
    }
}

พร้อมอัพเกรดทันที!

ในกรณีที่คุณใช้วิธีการเก่าคุณสามารถอัตโนมัติกับอธิการบดี

อ่านเพิ่มเติม

นี้เรียกว่าการฉีดนวกรรมิกมากกว่าบริการระบุตำแหน่งวิธีการ

เพื่ออ่านข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ให้ตรวจสอบการโพสต์ของฉันวิธีการรับพารามิเตอร์ใน Symfony ควบคุมวิธีทำความสะอาด

(ผ่านการทดสอบแล้วและฉันจะคอยอัปเดตสำหรับเวอร์ชันหลัก Symfony ใหม่ (5, 6 ... ))


วิธีการที่เรียบง่ายแบบใหม่ในหัวข้อนี้: tomasvotruba.cz/blog/2018/11/05/…
Tomáš Votruba

10

ฉันส่งตัวอย่างให้คุณด้วย swiftmailer:

parameters.yml

recipients: [email1, email2, email3]

บริการ:

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

ระดับของการบริการ:

protected $recipients;

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

8

ใน Symfony 4 คุณสามารถใช้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');
        // ...
    }
}

และในapp/config/services.yaml:

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

มันใช้งานได้สำหรับฉันทั้งในคอนโทรลเลอร์และคลาสของฟอร์ม รายละเอียดเพิ่มเติมสามารถพบได้ในบล็อก Symfony


1
ผ่านถุงพารามิเตอร์ทั้งหมดเป็นเหมือนผ่านภาชนะทั้งหมด มันสมเหตุสมผลแล้วใน "ถ้าบริการบางอย่างต้องการพารามิเตอร์คอนเทนเนอร์จำนวนมาก" (ยกมาจากโพสต์)
Tomáš Votruba

คุณหมายถึงการผ่านพารามิเตอร์ทั้งหมดทำให้เกิดปัญหาประสิทธิภาพหรือไม่
ghazaleh javaheri

นั่นเป็นหนึ่งในเหตุผล แต่ส่วนใหญ่สำหรับการอ่านได้ ถ้าฉันเห็นชื่อพารามิเตอร์$meetupApiKeyฉันรู้ว่าจะคาดหวังอะไรได้ดีกว่าในเล็กน้อย$parameterBag
Tomáš Votruba


0

ใน Symfony 4.3.1 ฉันใช้สิ่งนี้:

services.yaml

HTTP_USERNAME: 'admin'
HTTP_PASSWORD: 'password123'

FrontController.php

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

ไม่ทำงานใน 4.8 คุณแน่ใจหรือว่าทำงานสักวัน?
Ricardo Martins

ฉันลืมเรื่องนี้จริงๆ แต่ใช่มันอาจจะใช้ได้เพราะฉันโพสต์เฉพาะสิ่งที่ผ่านการทดสอบแล้ว!
Achraf JEDAY

1
ขออภัย Acharaf ฉันไม่รู้ แต่ใช้งานไม่ได้ในคอนโทรลเลอร์ ภายในคอนโทรลเลอร์ของคุณคุณสามารถเรียกใช้ getParameter โดยตรงโดยไม่มี DI $this->getParameter('foo')เช่น: นั่นคือสิ่งที่ฉันทำเพื่อให้ทำงานใน SF 4.8
Ricardo Martins

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.