Symfony2 config.yml에서 구성 설정을 어떻게 읽습니까?


191

내 config.yml 파일에 설정을 다음과 같이 추가했습니다.

app.config:
    contact_email: somebody@gmail.com
    ...

내 인생에서는 변수로 읽는 방법을 알 수 없습니다. 내 컨트롤러 중 하나에서 이와 같은 것을 시도했습니다.

$recipient =
$this->container->getParameter('contact_email');

그러나 오류가 발생합니다.

"contact_email"매개 변수를 정의해야합니다.

캐시를 지우고 Symfony2를 다시로드 한 사이트 설명서의 모든 곳을 보았지만이 작업을 수행하는 방법을 찾을 수 없습니다.

아마도 이것을 이해하기에는 너무 피곤할 것입니다. 누구든지 이것을 도울 수 있습니까?

답변:


194

contact_emailwithin app.config을 정의 하는 대신 parameters항목 에서 정의하십시오 .

parameters:
    contact_email: somebody@gmail.com

컨트롤러 내에서 전화를 걸면 작동합니다.


4
이것이 Dev / Prod 환경에서 어떻게 작동합니까? 테스트를 위해 이메일을 테스트 이메일로 보내고 싶습니다. 프로덕션은 또 다른 이메일을받을 것입니다
Phill Pafford

2
@Phill : symfony2에서 표준 swiftmailer를 사용하는 경우 config_dev.yml에서 다음 설정을 사용할 swiftmailer: delivery_address: dev@example.com 수 있습니다. 자세한 정보는 Symfony2 쿡북
Pierre

4
이 문장을 사용할 때 컨테이너 클래스를 어디서나 (컨트롤러, 엔티티, 클래스) 주입해야합니까 $ this-> container-> getParameter ( 'contact_email'); ? 또는 컨테이너 클래스를 주입하지 않고 그렇게하는 간단한 방법이 있습니까?
webblover

1
이 솔루션에 따르면 중첩 속성에 어떻게 액세스 할 수 있습니까?
Ousmane

1
@webblover 그냥 매개 변수 자체 사용하여 삽입 %parameter_name%(YAML에) 표기를 -
MauganRa

173

다른 답변에서 제안한 것처럼 contact_emailto 를 이동하는 방법 parameters.yml은 쉽지만 많은 번들을 처리하거나 중첩 된 구성 블록을 처리하는 경우 매개 변수 파일을 쉽게 어수선 할 수 있습니다.

  • 먼저 엄격하게 질문에 대답하겠습니다.
  • 나중에 공통 공간을 매개 변수로 사용하지 않고 서비스에서 해당 구성을 가져 오는 방법을 제공합니다.

첫 번째 접근 방식 : 분리 된 구성 블록, 매개 변수로 가져 오기

확장 기능 ( 여기서 확장 기능에 대한 자세한 내용 )을 사용하면이 블록을 다른 블록으로 쉽게 "분리" config.yml한 다음 컨트롤러에서 gettable 매개 변수로 삽입 할 수 있습니다.

DependencyInjection디렉토리 안의 Extension 클래스 안에 다음을 작성하십시오.

class MyNiceProjectExtension extends Extension
{
    public function load( array $configs, ContainerBuilder $container )
    {
        // The next 2 lines are pretty common to all Extension templates.
        $configuration = new Configuration();
        $processedConfig = $this->processConfiguration( $configuration, $configs );

        // This is the KEY TO YOUR ANSWER
        $container->setParameter( 'my_nice_project.contact_email', $processedConfig[ 'contact_email' ] );

        // Other stuff like loading services.yml
    }

그런 다음 config.yml에서 config_dev.yml을 설정하면

my_nice_project:
    contact_email: someone@example.com

config.yml내부 에서 처리하려면 동일한 네임 스페이스 MyNiceBundleExtensionConfiguration클래스가 필요 합니다.

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root( 'my_nice_project' );

        $rootNode->children()->scalarNode( 'contact_email' )->end();

        return $treeBuilder;
    }
}

그런 다음 원래 질문에서 원하는대로 컨트롤러에서 구성을 가져올 수 있지만 parameters.yml깨끗하게 유지하고 config.yml별도의 섹션에 설정하십시오 .

$recipient = $this->container->getParameter( 'my_nice_project.contact_email' );

두 번째 접근법 : 구성을 서비스에 주입하는 분리 된 구성 블록

비슷한 것을 찾고 있지만 서비스에서 구성을 얻는 독자에게는 "매개 변수"공통 공간을 어지럽히 지 않고 container서비스로 전달할 필요가없는 더 좋은 방법이 있습니다 (전체 컨테이너를 전달하는 것은 실습입니다. 기피).

위의 트릭은 여전히 ​​설정 공간의 매개 변수 공간에 "주입"합니다.

그럼에도 불구하고 서비스 정의를로드 한 후 서비스 setConfig()에만 해당 블록을 삽입하는 것과 같은 메소드 호출을 추가 할 수 있습니다 .

예를 들어, Extension 클래스에서

class MyNiceProjectExtension extends Extension
{
    public function load( array $configs, ContainerBuilder $container )
    {
        $configuration = new Configuration();
        $processedConfig = $this->processConfiguration( $configuration, $configs );

        // Do not add a paramater now, just continue reading the services.
        $loader = new YamlFileLoader( $container, new FileLocator( __DIR__ . '/../Resources/config' ) );
        $loader->load( 'services.yml' );

        // Once the services definition are read, get your service and add a method call to setConfig()
        $sillyServiceDefintion = $container->getDefinition( 'my.niceproject.sillymanager' );
        $sillyServiceDefintion->addMethodCall( 'setConfig', array( $processedConfig[ 'contact_email' ] ) );
    }
}

그런 다음 services.yml절대 변경없이 평소와 같이 서비스를 정의하십시오.

services:
    my.niceproject.sillymanager:
        class: My\NiceProjectBundle\Model\SillyManager
        arguments: []

그런 다음 SillyManager수업에서 메소드를 추가하십시오.

class SillyManager
{
    private $contact_email;

    public function setConfig( $newConfigContactEmail )
    {
        $this->contact_email = $newConfigContactEmail;
    }
}

이것은 스칼라 값 대신 배열에도 적용됩니다! 토끼 대기열을 구성하고 호스트, 사용자 및 비밀번호가 필요하다고 상상해보십시오.

my_nice_project:
    amqp:
        host: 192.168.33.55
        user: guest
        password: guest

물론 트리를 변경해야하지만 다음을 수행 할 수 있습니다.

$sillyServiceDefintion->addMethodCall( 'setConfig', array( $processedConfig[ 'amqp' ] ) );

그리고 서비스에서 :

class SillyManager
{
    private $host;
    private $user;
    private $password;

    public function setConfig( $config )
    {
        $this->host = $config[ 'host' ];
        $this->user = $config[ 'user' ];
        $this->password = $config[ 'password' ];
    }
}

도움이 되었기를 바랍니다!


첫 번째 접근 방식과 설명서의 차이점이 궁금한 경우 다음 MyNiceProjectExtension->load()줄 을 사용하여 메소드 의 구성 값이 매개 변수로 변환됩니다 $container->setParameter( 'my_nice_project.contact_email', $processedConfig[ 'contact_email' ]);. 고마워 Xavi!
jxmallett

완벽한 대답, 부끄러운 심포니는 매개 변수와 같은 방식으로 구성에 액세스 할 수 없습니다.
Martin Lyne

이것은 좋은 대답이지만 Symfony가 응용 프로그램을 "구성"하는 데 방해가되는 방식을 노출시킵니다. 특정 서비스를 작성하고 호출하여 액세스해야 할 때 임의의 환경 구성 파일을 갖는 것이 중요합니다. Symfony의 누군가가 거기에 앉아서 '개발자가 실제로 액세스 할 수있는 환경 특정 값을 응용 프로그램에 제공하고 싶을 수도 있습니다.'구성 파일의 요점이 아닌가? "STKTFANREO"디자인 패턴을 따르고 있습니다. "노브를 F'd로 설정하고 떼어냅니다"
eggmatters

여기에는 특히 병렬 자동 테스트를 배포하는 데 필요한 여러 응용 프로그램이 있으며, 특히 팀이 다른 응용 프로그램 (예 : 사용자 프런트 엔드 응용 프로그램)의 다른 여러 팀에서 사용하는 모델 또는 논리 인 번들을 개발할 때 다른 하나는 관리 패널 웹 프론트이고 다른 하나는 REST API입니다. 이들 각각은 서로 다른 구성을 원하는 다른 응용 프로그램입니다. 여기에는 여러 환경 (생산, 사전 프로덕션, 테스트, 개발 등)이 곱해집니다. 이는 단일 회사에서 12 개 또는 15 개의 구성으로 쉽게 얻을 수 있습니다.
Xavi Montero

@XaviMontero 나는 당신의 지시에 따라 SECOND APPROACH : var_dump $ this-> contact_email 또는 setConfig () 함수에 exit ()를 추가하면 종료되지 않습니다. setConfig가 호출되지 않는 것 같습니다
user742736

35

더글라스의 대답에 추가해야합니다. 글로벌 구성에 액세스 할 수 있지만 symfony는 다음과 같은 일부 매개 변수를 변환합니다.

# config.yml
... 
framework:
    session:
        domain: 'localhost'
...

아르

$this->container->parameters['session.storage.options']['domain'];

var_dump를 사용하여 지정된 키 또는 값을 검색 할 수 있습니다.


17

번들에 대한 일부 구성 매개 변수를 노출하려면이를위한 문서를 참조해야합니다. 꽤 쉽습니다 :)

링크는 다음과 같습니다 . 번들의 시맨틱 구성을 노출하는 방법


솔직히이 질문은 2 년 전에 제기 된 것이 었습니다. 당시에는 위의 기사가 없었습니다.
josef.van.niekerk

10
나는 그 진술에 동의합니다. 요즘 누군가 가이 기사를 열면 대답을 설정했습니다. 부정적인 평가에 감사드립니다-당신은 내 하루를 만들었습니다.
Nikola Petkanski

나의 사과, 이제 내가 생각하기에, 나의 downvote는 요구되지 않았다. 귀하의 기여에 감사 드리며, 찬성하려고했지만 더 이상 허용하지 않습니다. 이 링크가 가장 도움이되며 다른 사람들도 도움이 될 것입니다! 어쩌면 관리자가 내 downvote를 변경하는 데 도움을 줄 수 있습니까 ???
josef.van.niekerk

다시 클릭하면 실행 취소 할 수 있습니다.
Nikola Petkanski

투표를 마치거나 메시지가 편집 될 때까지 X (5?) 분 이상 투표를 취소 할 수 없습니다.
cheesemacfly


3

http://tutorial.symblog.co.uk/의 코드 예제에서 쉬운 방법을 배웠습니다.

1) ZendeskBlueFormBundle 및 파일 위치를 확인하십시오.

# myproject/app/config/config.yml

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: @ZendeskBlueFormBundle/Resources/config/config.yml }

framework:

2) Zendesk_BlueForm.emails.contact_email 및 파일 위치에 유의하십시오.

# myproject/src/Zendesk/BlueFormBundle/Resources/config/config.yml

parameters:
    # Zendesk contact email address
    Zendesk_BlueForm.emails.contact_email: dunnleaddress@gmail.com

3) 컨트롤러의 $ client 및 파일 위치에서 어떻게 얻습니까?

# myproject/src/Zendesk/BlueFormBundle/Controller/PageController.php

    public function blueFormAction($name, $arg1, $arg2, $arg3, Request $request)
    {
    $client = new ZendeskAPI($this->container->getParameter("Zendesk_BlueForm.emails.contact_email"));
    ...
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.