18

我有一个像这样的混合数组(手机号码和实体):

$targets = array();

$targets[] = '+32647651212';
$targets[] = new Customer();

在我的 Twig 模板中,我必须调用getMobile()if targetis aCustomer或仅打印数字(如果它实际上是数字(string))。

instanceofTwig 中有类似运算符的东西吗?

<ul>
{% for target in targets %}
   <li>{{ target instance of MyEntity ? target.getMobile : target }}</li>
   {% else %}
       <li>Nothing found.</li>
</ul>
4

9 回答 9

42

在 \Twig_Extension 你可以添加测试

public function getTests()
{
    return [
        'instanceof' =>  new \Twig_Function_Method($this, 'isInstanceof')
    ];
}

/**
 * @param $var
 * @param $instance
 * @return bool
 */
public function isInstanceof($var, $instance) {
    return  $var instanceof $instance;
}

然后像这样使用

{% if value is instanceof('DateTime') %}
于 2014-11-20T11:53:10.543 回答
21

更新 10-2021

请注意,此答案是为 symfony 3 和 twig 2 编写的。 如果您使用更新的版本,请参阅本文中@Garri Figueroa 的答案

正如您在twig 文档\Twig_Extension中看到的那样,该类\Twig_SimpleTest现在已被弃用。

如果您使用更新版本的 symfony(我推荐它),请使用新的类AbstractExtensionTwigFunction等等 https://symfony.com/doc/5.3/templating/twig_extension.html


旧版本:symfony 3.4

这是使用 Extension 在 twig中执行instanceof运算符的好方法:

1)在你想要的地方创建你的扩展文件

(例如:src/OC/YourBundle/Twig/InstanceOfExtension.php)

使用 \Twig_Extension 你可以做很多事情,过滤器,功能,但现在我们将创建一个测试。

所以我们实现了函数 getTests(),并在其中创建了一个新的 \Twig_SimpleTest

第一个参数是您创建的测试的名称,第二个参数是可调用的。(可以是函数(){})。

<?php

namespace OC\YourBundle\Twig;

class InstanceOfExtension extends \Twig_Extension {

    public function getTests() {
        return array(
            new \Twig_SimpleTest('instanceof', array($this, 'isInstanceOf')),
         );
     }

    public function isInstanceOf($var, $instance) {
        $reflexionClass = new \ReflectionClass($instance);
        return $reflexionClass->isInstance($var);
    }
}

2) 在 services.yml 中注册

(例如:src/OC/YourBundle/Resources/config/services.yml)

services:

    [...may you have other services ...]

    app.twig_extension:
        class: OC\YourBundle\Twig\InstanceOfExtension
        public: false
        tags:
          - { name: twig.extension }

3)然后像这样在树枝中使用它

{{ myvar is instanceof('\\OC\\YourBundle\\Entity\\YourEntityOrWhatEver') }}

来自 Adrien Brault => https://gist.github.com/adrienbrault/7045544

于 2017-10-20T11:10:18.380 回答
6

我对 Symfony 4.3 的解决方案

1) 在 src/Twig 文件夹中创建 AppExtension 类。(自动检测类)。

2) 扩展 AbstractExtension 类:

namespace App\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigTest;

class AppExtension extends AbstractExtension
{
    public function getTests()
    {
        return [
            new TwigTest('instanceof', [$this, 'isInstanceof'])
        ];
    }

    /**
     * @param $var
     * @param $instance
     * @return bool
     */
    public function isInstanceof($var, $instance) {
        return  $var instanceof $instance;
    }
}

3)然后使用相同的 valdas.mistolis 代码回答:

{% if value is instanceof('DateTime') %}

4) 感谢 valdas.mistolis 和 symfony 文档,我得到了自己的解决方案: Twig Extension 模板

于 2019-10-16T18:35:50.410 回答
3

从 PHP 5.5.0 开始,您可以通过以下方式比较类名:

{{ constant('class', exception) is constant('\\Symfony\\Component\\HttpKernel\\Exception\\HttpException') }}

当您需要严格比较类名时,此代码段可以在特定情况下提供帮助。如果您需要检查接口的实现或检查继承,最好创建上述树枝扩展。

于 2018-07-25T13:42:05.400 回答
0

另一个解决方案:

class A {
    ...
    public function isInstanceOfB() {
        return $this instanceof B;
    }
}

class B extends A {}
class C extends A {}

然后在你的树枝上:

{{ a.isInstanceOfB ? ... something for B instance ... : ... something for C instance ... }}

或者

{% if a.isInstanceOfB %}
    ... do something for B instance ...
{% else %}
    ... do something for C instance ...
{% endif %}
于 2017-01-16T15:25:15.933 回答
0

其他没有 ReflectionClass 和树枝过滤器的解决方案:

首先你需要一个 TwigExtension 类。然后,添加一个函数作为树枝过滤器或树枝函数,

namespace App\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;

class TwigExtension extends AbstractExtension

    /**
     * @return array|\Twig_Filter[]
     */
    public function getFilters()
    {
        return [           
            new TwigFilter('is_instance_of', [$this, 'isInstanceOf'])
        ];
    }

    /**
     * @param $object
     * @param $class
     * @return bool
     */
    public function isInstanceOf($object, $class): bool
    {
        return is_a($object, $class, true);
    }
}

在树枝模板中:


{% if true is same as (object|is_instance_of('ClassName')) %}
   // do some stuff
{% endif %} 

检查http://php.net/manual/fr/function.is-a.php

于 2018-05-10T12:47:45.853 回答
0

遍历 Symfony 表单时的另一个示例:

namespace App\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigTest;
use App\Document\Embeded\Image;
use App\Document\Embeded\Gallery;
use App\Document\Embeded\Article;

class AppExtension extends AbstractExtension
{
    public function getTests()
    {
        return [
            new TwigTest('image', [$this, 'isImage']),
            new TwigTest('gallery', [$this, 'isGallery']),
            new TwigTest('article', [$this, 'isArticle']),
        ];
    }

    public function isImage($var) {
        return $var instanceof Image;
    }

    public function isGallery($var) {
        return $var instanceof Gallery;
    }

    public function isArticle($var) {
        return $var instanceof Article;
    }
}

枝条

{% if form.vars.data is gallery %}
    This is a Gallery 
{% elseif  form.vars.data is article %}
    This is an Article
{% endif %}
于 2020-05-12T07:28:38.247 回答
-6

default像这样在 Twig 中使用过滤器:

{{ target.mobile|default(target) }}
于 2012-05-28T19:15:01.433 回答
-10

很老了,但我在这里看不到实现这一目标的另一种可能性:

实体:

public function __toString()
{
    return 'NameOfYourEntity';
}

枝条:

{{ entity }}
于 2016-05-08T19:28:31.407 回答