Symfony2:如何从树枝过滤器/扩展中的parameters.yml获取容器参数


Symfony2: How to get container parameters from parameters.yml in a twig filter/extension?

我有文件parameters.yml:

parameters:
    ............
    image_news_url: http://image.dev/news/

现在,在我的捆绑包中,我创建了一个新的分支扩展:

// src/DesktopBundle/Twig/AppExtension.php
namespace App'DesktopBundle'Twig;
use Symfony'Component'DependencyInjection'ContainerBuilder;
class AppExtension extends 'Twig_Extension
{
public function getFilters()
{
    return array(
        new 'Twig_SimpleFilter('get_image', array($this, 'getImage')),
    );
}
public function getImage($domen, $image_id)
{
    $o_container = new ContainerBuilder();
    switch($domen){
        case 'news':
            return sprintf('%s%s',$o_container->getParameter('image_news_url'),$image_id.'.slide.jpg');
            break;
    }
}
public function getName()
{
    return 'app_extension';
}

}我有一个错误:You have requested a non-existent parameter "image_news_url。你能帮我吗?我不明白为什么我不能提前访问parameters.yml.Thx,很抱歉我的英语

这个问题是由您尝试自己构建容器的事实引起的。

$o_container = new ContainerBuilder();

这是错误的。

如果你想访问它,你只需要将容器注入到你的扩展中。

配置

services:
    # [..]    
    your.twig_extension:
        class: Your'Namespace'YourExtension
        public: false
        arguments: [ "@service_container" ]
        tags:
            - { name: twig.extension }

类别

use Symfony'Component'DependencyInjection'ContainerInterface;
namespace Your'Namespace;
class YourExtension 
{
    /** @var ContainerInterface */
    protected $container;
    /** @param ContainerInterface $container */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }
    /** @return string */
    function getImage()
    {
        // some logic here
        return $this->container->getParameter('image_news_url');
    }

我假设您希望应用一些附加逻辑来选择扩展中的参数。否则你可以简单地:

  • 仅注入参数本身%image_news_url%
  • 使用twig.globals配置指令

文档中的"使用服务容器参数"一章中有一个示例。

app/config/parameters.yml

image_news_url: "http://some-url.tld"

app/config/config.yml

twig:
    globals:
       image_news_url: %image_news_url%

模板

{{ image_news_url }}

$o_container = new ContainerBuilder();

简单地声明一个ContainerBuilder的新实例不会让您访问另一个(已经存在的)实例。您需要注入已经存在的实例。而且-你实际上并不想要,你只想要一个参数,所以你可以简单地注入它。

在创建Twig扩展的服务定义中,需要注入此参数。所以,在services.xml文件中应该有这样的内容。。。

    <service id="twig.extension.desktop_bundle" class="App'DesktopBundle'Twig'AppExtension" public="false">
        <argument>%image_news_url%</argument>
        <tag name="twig.extension" />
    </service>

然后,在Extension类中,您需要使用一个构造函数:

namespace App'DesktopBundle'Twig;
use Symfony'Component'DependencyInjection'ContainerBuilder;
class AppExtension extends 'Twig_Extension
{
    private $url;
    public function __construct($url)
    {
        $this->url = $url;
    }
    // ...
}

现在,您可以在任何需要值的地方使用$this->url

阅读依赖注入以获取更多信息。