Экземпляр оператора в Twig/Symfony 2?

У меня смешанный массив, подобный этому (мобильные номера и сущности):

$targets = array();

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

В моем шаблоне Twig мне нужно позвонить getMobile(), если target является Customer или просто напечатать номер, если он фактически является числом (string).

Есть ли что-то вроде оператора instanceof в Twig?

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

Ответ 1

В\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') %}

Ответ 2

Вот хороший способ сделать оператор 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') }}

Источник от Эдриан Браулт => https://gist.github.com/adrienbrault/7045544

Ответ 3

Начиная с PHP 5.5.0, вы можете сравнивать имена классов следующим образом:

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

Этот фрагмент может помочь в особых случаях, когда вам нужно строгое сравнение имен классов. Если вам нужно проверить реализацию интерфейса или проверить наследование, лучше создать расширение ветки, описанное выше.

Ответ 4

Другое решение без ReflectionClass:

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

Проверить http://php.net/manual/fr/function.is-a.php

Ответ 5

Другое решение:

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 %}

Ответ 6

Мое решение для Symfony 4.3

1) Создайте класс AppExtension в папке src/Twig. (Класс определяется автоматически).

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

Ответ 8

Довольно старый, но я не вижу здесь еще одной хорошей возможности достичь этого:

Enity:

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

Twig:

{{ entity }}