在 Symfony2 中使用来自 Twig 扩展的辅助服务

Arc*_*ico 1 dependency-injection symfony twig

我正在尝试设置一个以这种方式工作的树枝过滤器: {{entities|fieldnames}} 将返回一个包含实体对象属性名称的数组。我的问题是,在阅读并尝试了几个小时之后,我无法从 Twig Extension php 中执行 $this->container->get("helpers") 。似乎我没有正确链接服务容器......请帮助;)

错误:在 /Users/a77/Dropbox/06.Proyectos/2011 U-Vox/DEV U-Vox/Uvox Web/src/Acme/DemoBundle/Extension/FieldnamesTwigExtension 中的非对象上调用成员函数 get()。 php 第 38 行

或者如果构造没有 =null 错误 ContextErrorException: Catchable Fatal Error: Argument 1 passed to Acme\DemoBundle\Extension\FieldnamesTwigExtension::__construct() 必须是 Acme\DemoBundle\Extension\Container 的一个实例,没有给出,调用

服务.yml

服务:

helpers:
    class:        Acme\DemoBundle\Services\Helpers

twig.extension.acme.demo:
    class:        Acme\DemoBundle\Twig\Extension\DemoExtension
    arguments:    [twig.loader]

acme.demo.listener:
    class:        Acme\DemoBundle\EventListener\ControllerListener
    arguments:    [twig.extension.acme.demo]

fieldnames:
    class: Acme\DemoBundle\Extension\FieldnamesTwigExtension
    arguments:  [@service_container]
Run Code Online (Sandbox Code Playgroud)

扩展名\字段名TwigExtension.php

use Symfony\Component\DependencyInjection\ContainerInterface as Container;
namespace Acme\DemoBundle\Extension;

class FieldnamesTwigExtension extends \Twig_Extension {
private $container;
public function __construct(Container $container=null)
{
    $this->container = $container;
    //var_dump ($container); exit; //  prints null !!!

}
 protected function get($service)
{
    return $this->container->get($service);
}

public function getFilters() {
    return array(
        'fieldnames' => new \Twig_Filter_Method($this, 'fieldnamesFilter'),
    );
}

public function getName() {
    return 'fieldnames_twig_extension';
}

public function fieldnamesFilter($obj) {
    if (is_array($obj)) {
        $first = $obj[0];

// GET (HELPERS) NOT WORKING :

       $fieldnames = $this->container->get("helpers")->getFieldnames($first);
        return $fieldnames;
    }
    return null;
}

public function twig_array_get_function($array, $name) {
    return $array[$name];
}

}
Run Code Online (Sandbox Code Playgroud)

Helpers.php

namespace Acme\DemoBundle\Services;

class Helpers {

public function sum($n1, $n2) {
    return $n1 + $n2;
}

public function getFieldnames($entities) {
    $reflect = new \ReflectionClass($entities[0]);
    $props = $reflect->getProperties();
    $fieldnames = Array();
    foreach ($props as $prop) {
        $fieldnames[] = $prop->getName();
    }
    return $fieldnames;
 }

}
Run Code Online (Sandbox Code Playgroud)

AcmeDemoExtension.php

命名空间 Acme\DemoBundle\DependencyInjection;

使用 Symfony\Component\DependencyInjection\ContainerBuilder; 使用 Symfony\Component\DependencyInjection\Loader\YamlFileLoader; 使用 Symfony\Component\HttpKernel\DependencyInjection\Extension;使用 Symfony\Component\Config\FileLocator; 使用 Symfony\Component\DependencyInjection\Definition; // 添加

类 AcmeDemoExtension 扩展扩展 {

public function load(array $configs, ContainerBuilder $container) {

    $definition = new Definition('Acme\DemoBundle\Extension\AccessTwigExtension');
    $definition->addTag('twig.extension');
    $container->setDefinition('access_twig_extension', $definition);

    $definition2 = new Definition('Acme\DemoBundle\Extension\FieldnamesTwigExtension');
    $definition2->addTag('twig.extension');
    $container->setDefinition('fieldnames_twig_extension', $definition2);


    $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
    $loader->load('services.yml');
}

public function getAlias() {
    return 'acme_demo';
}

 }
Run Code Online (Sandbox Code Playgroud)

TaK*_*kEr 5

我在我的应用程序上尝试了您的代码,但遇到了同样的错误。要解决它:

Acme\DemoBundle\DependencyInjection\AcmeDemoExtension.php

删除此行:

$definition2 = new Definition('Acme\DemoBundle\Extension\FieldnamesTwigExtension');
$definition2->addTag('twig.extension');
$container->setDefinition('fieldnames_twig_extension', $definition2);
Run Code Online (Sandbox Code Playgroud)

Acme\DemoBundle\Resources\config\services.yml

替换此行:

fieldnames:
    class: Acme\DemoBundle\Extension\FieldnamesTwigExtension
    arguments:  [@service_container]
Run Code Online (Sandbox Code Playgroud)

经过 :

fieldnames:
    class: Acme\DemoBundle\Extension\FieldnamesTwigExtension
    arguments:  [@service_container]
    tags: [{ name: twig.extension }]
Run Code Online (Sandbox Code Playgroud)

  • 你打败了我,虽然我认为只注入助手而不是完整的容器是一个稍微好一点的方法。 (2认同)