Экземпляр оператора в 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
Ответ 7
Используйте default
фильтр в Twig следующим образом:
{{ target.mobile|default(target) }}
Ответ 8
Довольно старый, но я не вижу здесь еще одной хорошей возможности достичь этого:
Enity:
public function __toString()
{
return 'NameOfYourEntity';
}
Twig:
{{ entity }}