Làm cách nào để đọc từ tham số.yml trong bộ điều khiển trong symfony2?


146

Tôi đã đặt một vài biến tùy chỉnh trong ứng dụng / config / tham số.yml của mình.

parameters:
    api_pass: apipass
    api_user: apiuser

Tôi cần truy cập chúng từ bộ điều khiển của mình và đã cố gắng tìm nạp chúng bằng

$this->get('api_user');

từ trong tập tin điều khiển của tôi. Khi tôi thử điều này, tôi nhận được thông báo lỗi này:

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

cách chính xác để làm điều này là gì?

Câu trả lời:


296

Trong Symfony 2.6 và các phiên bản cũ hơn , để có được một tham số trong bộ điều khiển - bạn nên lấy container trước, sau đó - tham số cần thiết.

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

Chương tài liệu này giải thích nó.

Trong khi $this->get()phương thức trong bộ điều khiển sẽ tải một dịch vụ ( doc )

Trong Symfony 2.7 và các phiên bản mới hơn , để có được một tham số trong bộ điều khiển, bạn có thể sử dụng như sau:

$this->getParameter('api_user');

3
Lưu ý rằng getphương thức trong bộ điều khiển cũng sử dụng bộ chứa, nhưng nó chỉ có thể nhận các dịch vụ từ một bộ chứa, không phải các tham số. Bạn cần getParameterlấy thông số.
Wouter J

Khi tôi thử, $this->getContainer()->getParameter('api_user');tôi gặp lỗi nghiêm trọng: Gọi đến phương thức không xác định ..Longpath .. \ Controller :: getContainer ().
Bohr

1
@Bohr xin lỗi, phiên bản khác nhau của Symfony2. Tôi đã chỉnh sửa câu trả lời của mình - kiểm tra ngay bây giờ;)
Vitalii Zurian


Symfony 2.7 trở lên: $this->hasParameter()chưa hoạt động.
Saman Mohamadi

23

Con đường sạch - 2018+, Symfony 3.4+

Kể từ năm 2017 và Symfony 3.3 + 3.4 có nhiều cách dễ dàng hơn - dễ cài đặt và sử dụng.

Thay vì sử dụng mô hình chống định vị bộ chứa và dịch vụ / tham số, bạn có thể truyền tham số cho lớp thông qua hàm tạo của nó . Đừng lo lắng, đó không phải là công việc đòi hỏi thời gian, mà là thiết lập một lần và quên phương pháp tiếp cận.

Làm thế nào để thiết lập nó trong 2 bước?

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. Bất kỳ 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"
    }
}

Nâng cấp ngay lập tức!

Trong trường hợp bạn sử dụng phương pháp cũ hơn, bạn có thể tự động hóa nó với Rector .

Đọc thêm

Điều này được gọi là tiêm xây dựng trên phương pháp tiếp cận dịch vụ định vị .

Để đọc thêm về điều này, hãy kiểm tra bài đăng của tôi Cách lấy tham số trong Trình điều khiển Symfony theo cách sạch .

(Nó đã được thử nghiệm và tôi giữ cho nó được cập nhật cho phiên bản chính Symfony mới (5, 6 ...)).


Cách tối giản mới về chủ đề này: tomasvotruba.cz/blog/2018/11/05/ Khăn
Tomáš Votruba

10

Tôi gửi cho bạn một ví dụ với swiftmailer:

tham số.yml

recipients: [email1, email2, email3]

dịch vụ:

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

lớp dịch vụ:

protected $recipients;

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

8

Trong Symfony 4, bạn có thể sử dụng 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');
        // ...
    }
}

và trong app/config/services.yaml:

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

Nó hoạt động cho tôi trong cả hai lớp điều khiển và biểu mẫu. Thông tin chi tiết có thể được tìm thấy trong blog Symfony .


1
Vượt qua toàn bộ túi thông số cũng giống như vượt qua cả một container. Điều này chỉ có ý nghĩa trong "nếu một số dịch vụ cụ thể cần nhiều thông số về container" (trích từ bài đăng)
Tomáš Votruba

Vì vậy, bạn có nghĩa là vượt qua toàn bộ tham số gây ra vấn đề trong hiệu suất?
ghazaleh javaheri

Đó là một trong những lý do, nhưng chủ yếu là để dễ đọc. Nếu tôi thấy tên tham số, $meetupApiKeytôi biết những gì sẽ mong đợi tốt hơn một chút$parameterBag
Tomáš Votruba


0

Trong Symfony 4.3.1 tôi sử dụng điều này:

dịch vụ.yaml

HTTP_USERNAME: 'admin'
HTTP_PASSWORD: 'password123'

FrontControll.php

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

Không hoạt động trong 4.8. Bạn có chắc chắn nó làm việc một ngày nào đó?
Ricardo Martins

Tôi thực sự quên mất điều này nhưng có lẽ nó hoạt động vì tôi chỉ đăng những thứ được thử nghiệm!
Achraf

1
Xin lỗi, Acharaf. Tôi không biết, nhưng không làm việc trong bộ điều khiển của tôi. Trong bộ điều khiển của bạn, bạn có thể gọi getParameter trực tiếp, không có DI. Tức là : $this->getParameter('foo'). Đó là những gì tôi đã làm để làm cho nó hoạt động trong SF 4.8.
Ricardo Martins

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.