Symfony2에서 번들과 관련된 파일 액세스


83

Symfony2 앱의 라우팅 구성에서 다음과 같은 파일을 참조 할 수 있습니다.

somepage:
    prefix: someprefix
    resource: "@SomeBundle/Resources/config/config.yml"

컨트롤러 또는 다른 PHP 코드 내에서 번들과 관련된 파일에 액세스하는 방법이 있습니까? 특히 Symfony \ Component \ Yaml \ Parser 개체를 사용하여 파일을 구문 분석하려고하는데 해당 파일을 절대적으로 참조하고 싶지 않습니다. 기본적으로 이렇게하고 싶습니다.

$parser = new Parser();
$config = $parser->parse( file_get_contents("@SomeBundle/Resources/config/config.yml") );

Symfony \ Component \ Finder \ Finder 클래스를 확인했지만 그게 내가 찾고있는 것 같지 않습니다. 어떤 아이디어? 아니면 더 나은 방법을 완전히 간과하고 있습니까?

답변:


179

사실이를 위해 사용할 수있는 서비스 인 커널 ( $this->get('kernel'))이 있습니다. 라는 메서드가 locateResource()있습니다.

예를 들면 :

$kernel = $container->getService('kernel');
$path = $kernel->locateResource('@AdmeDemoBundle/path/to/file/Foo.txt');

5
내가 찾던 바로 그것! $ this-> get ( 'kernel')-> locateResource ( "@ SomeBundle / Resources / config / config.yml"); // 완벽하게 작동했습니다
Thomas Kelley

9
@ tomtheman5 : 예외를 포착해야합니다. 이 메서드는 \InvalidArgumentException파일을 찾을 수 없거나 이름이 유효하지 않은 \RuntimeException경우, 이름에 유효하지 않은 / 안전하지 않은 문자가 포함 된 경우를 throw 합니다.
kgilden 2011 년

2
당신에게 +1 이상의 것을주고 싶습니다.
독감

커널에 액세스 할 수있는 (또는해야하는) 교리 엔티티 내부에서이 방법을 어떻게 사용합니까 (아마도)?
Michael.Lumley 2014 년

1
@Morslamina fazy의 답변을 확인하십시오.
Tek

78

Thomas Kelley의 대답은 훌륭하지만 작동하지만 종속성 주입을 사용하거나 코드를 커널에 직접 연결하고 싶지 않은 경우 FileLocator 클래스 / 서비스를 사용하는 것이 좋습니다.

$fileLocator = $container->get('file_locator');
$path = $fileLocator->locate('@MyBundle/path/to/file.txt')

$fileLocator의 인스턴스가 \Symfony\Component\HttpKernel\Config\FileLocator됩니다. $path파일의 전체 절대 경로가됩니다.

file_locator서비스 자체가 커널을 사용 하더라도 훨씬 더 작은 종속성입니다 (자신의 구현을 대체하는 것이 더 쉬움, 테스트 이중 사용 등).

종속성 주입과 함께 사용하려면 :

# services.yml

services:
    my_bundle.my_class:
        class: MyNamespace\MyClass
        arguments:
            - @file_locator

# MyClass.php

use Symfony\Component\Config\FileLocatorInterface as FileLocator;

class MyClass
{
    private $fileLocator;

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

    public function myMethod()
    {
        $path = $this->fileLocator->locate('@MyBundle/path/to/file.txt')
    }
}

좋은 점,하지만 FileLocator은 당신이 경우 :) 대신 커널의 FileLocator 주입 더 나은 아무것도하지 않고, KernelInterface 그래서 기본적으로, 주입 얻는다
tomazahlin

10
나는 당신의 요지를보고 그것을 생각했습니다. 그러나 문제는 "어떤 코드가로드 / 실행됩니까?"가 아니라 "어떤 코드에 MyClass의존합니까?"입니다. 현재 FileLocator구현에서는를 사용 KernelInterface하지만 향후 변경 될 경우 MyClass이를 알 필요가 없습니다. 또한 이제 MyClass실제로 필요한 것이 무엇인지 명확 해졌습니다 (다른 커널 기능과 결합하려는 유혹이 적음). 갖는 생성자는 아마 요구해야 모든 것을 말했다 Symfony\Component\Config\FileLocatorInterface보다는 Symfony\Component\HttpKernel\Config\FileLocator. 그런 다음 직접 작성할 수 있습니다.
fazy

3
이것이 더 나은 답변입니다
NDM

6

를 사용 하여 애플리케이션 $container->getParameter('kernel.root_dir')app폴더 를 가져 오고 원하는 파일로 디렉토리를 검색 할 수 있습니다.


번들은 모든 디렉토리에있을 수 있습니다. 일반적인 예 : src/Acme/Bundle/MyBundle, src/Acme/MyBundlevendor/acme/my-bundle/src.
Marius Balčytis 2015

3

에있는 파일에서이를 수행 하려면 현재 파일의 전체 경로를 가져 오는 데 src/.../SomeBundle/...사용할 수 있습니다 __DIR__. 그런 다음 Resources/...경로를 추가하십시오.

$foo = __DIR__.'/Resources/config/config.yml';

@ruudy "유료 플랜에 등록 된 사용자 만 규칙 설명에 대한 전체 액세스 권한을 얻을 수 있습니다.이 페이지에는 구독을 통해 얻을 수있는 항목의 샘플이 표시됩니다."
prehfeldt

나는 지불하지 않았고 전체 설명과 해결 방법에 대한 설명을 볼 수 있습니다. 등록 만하면 될 수도 있습니다.
ruudy

등록이 되었으니 페이지를 볼 수 있습니다. 우선 그것은 "안돼야한다"고 "하지 말아야한다"는 말이 아닙니다. 두 번째로 이것은 코드를 공개적으로 공개하거나 나중에 리소스 경로를 재정의 할 계획 인 경우에만 중요합니다. 내 비공개 소스 프로젝트에서는 이런 일이 발생하지 않으므로 이것은 나에게 그렇게 중요하지 않습니다. 이 점이 중요한 경우 사용할 컨텍스트에 따라 다릅니다. 그럼에도 불구하고 힌트를 주셔서 감사합니다.
prehfeldt

권장 사항을 따르면 경로를 모의하거나 테스트 목적으로 사용할 수 있습니다. Im 영어 네이티브가 아닙니다. Symfony2와 같은 프레임 워크에서는 훨씬 적게이 PHP 상수를 가능한 한 사용하지 않는 것이 좋습니다.
ruudy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.