如何在Symfony2 Twig模板中调用静态函数

11
如何在Twig模板中调用我的静态函数而不经过控制器?
例如:
...
{{ MyStaticClass::getData() }}
...

我的静态类:

class MyStaticClass {
    const v1 = 'Value1';
    const v2 = 'Value2';
    ...

    public static function getData() {
        ...

        return $data;
    }
}
3个回答

20

有时,与其编写Twig扩展,更简单/更轻量的解决方案是将带有静态方法的类的新实例直接传递给Twig。

例如

// ...
$viewVars['MyStaticClass'] = new MyStaticClass();
// ...
$html = $twig->render('myTemplate.html.twig', $viewVars);

还有在Twig中:

{{ MyStaticClass.getData() }}

16

你不能在twig模板中直接调用PHP。你需要创建一个过滤器或函数来完成你所需的操作。

$twig         = new Twig_Environment($loader, $params);
$twigFunction = new Twig_SimpleFunction('MyStaticClass', function($method) {
    MyStaticClass::$method
});
$twig->addFunction($twigFunction);

然后在您的Twig模板中只需要这样做:

{{ MyStaticClass('getData') }}

当然,上述示例假定MyStaticClass在您的twig所在的范围内。

Symfony示例

您必须创建twig扩展。以下是示例:

namespace PurpleNeve\Web\PNWebBundle\Extensions;

use PurpleNeve\Web\PNWebBundle\DependencyInjection\CurrencyConverter;

class TwigCurrency extends \Twig_Extension
{
    private $converter;

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

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

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

    public function getConversionBetween($amount, $isoFrom, $isoTo="USD")
    {
        try {
          $value = $this->converter->convertAmount($amount, $isoFrom, $isoTo);
          return round($value,2);
        } catch(\Exception $e) {
          return "?";
        }
    }
}

这是我创建的一个扩展示例,用于在twig中将一种货币转换为另一种货币。

要实现它,您需要在services.yml中为它创建一个服务对象。

parameters:
    currency_converter.class: PurpleNeve\Web\PNWebBundle\DependencyInjection\CurrencyConverter

services:
    currency_converter:
        class: "%currency_converter.class%"
        arguments : [@doctrine.orm.entity_manager]

    twig.extension.currency:
        class: PurpleNeve\Web\PNWebBundle\Extensions\TwigCurrency
        tags:
            - { name: 'twig.extension' }
        arguments : [ @currency_converter ]

那么,像上面一样,在 Twig 中我可以使用 {{ convertCurrency(55505, 'CAD', 'USD) }} 调用该类和函数。


我明白了,上面的代码应该添加在哪里?你所指的“在你的twig范围内”是什么意思? - overshadow
无论哪个文件正在渲染您的Twig模板,请在渲染之前添加该代码。 - Sean
在范围内意味着你的类可以从声明代码的位置被访问或调用。 - Sean
是的,我会为您更新示例 - 刚刚注意到了Symfony2标签。 - Sean
1
我添加了一个示例,这是我在其中一个项目中编写的Twig扩展程序,用于转换货币。 - Sean
显示剩余3条评论

11

一种通用的方法是注册一个名为callstatic的Twig助手函数来进行调用。

$twig->addFunction(new \Twig_SimpleFunction('callstatic', function ($class, $method, ...$args) {
    if (!class_exists($class)) {
        throw new \Exception("Cannot call static method $method on Class $class: Invalid Class");
    }

    if (!method_exists($class, $method)) {
        throw new \Exception("Cannot call static method $method on Class $class: Invalid method");
    }

    return forward_static_call_array([$class, $method], $args);
}));

这种方法的主要优点是它可以与任何类和方法组合一起使用。

用法:

{# This will call \Mynamespace\Mypackage\Myclass::getStuff(); #}
{% set result = callstatic('\\Mynamespace\\Mypackage\\Myclass', 'getStuff') %}

它还支持参数:

{# This will call \Mynamespace\Mypackage\Myclass::getStuff('arg1', 'arg2'); #}
{% set result = callstatic('\\Mynamespace\\Mypackage\\Myclass', 'getStuff', 'arg1', 'arg2') %}

1
相当优雅的解决方案!+1教我关于forward_static_call_array - vdwijngaert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接