Ответ 1
Установите флаг и используйте цикл. Впоследствии вы можете использовать флаг в условиях if.
{% set flag = 0 %}
{% for tag in tasks.tags %}
{% if tag.id == "20" %}
{% set flag = 1 %}
{% endif %}
{% endfor %}
{{ flag }}
Чтобы просто проверить, содержит ли массив определенное значение, которое я сделал бы:
{% if myVar in someOtherArray|keys %}
...
{% endif %}
Однако мой массив многомерен.
$tasks = array(
'someKey' => 'someValue',
...
'tags' => array(
'0' => array(
'id' => '20',
'name' => 'someTag',
),
'1' => array(
'id' => '30',
'name' => 'someOtherTag',
),
),
);
Я бы хотел проверить, имеет ли тег $tasks['tags']
идентификатор тега 20. Надеюсь, я не смущаю вас, используя формат массива PHP.
Установите флаг и используйте цикл. Впоследствии вы можете использовать флаг в условиях if.
{% set flag = 0 %}
{% for tag in tasks.tags %}
{% if tag.id == "20" %}
{% set flag = 1 %}
{% endif %}
{% endfor %}
{{ flag }}
это больше похоже на многомерный цикл в случае необходимости
{% for animals in array %}
{% set dogs = animals.dogs %}
{% for dog in dogs %}
{{ dump(dog.type) }}
{% endfor%}
{% endfor %}
Для оператора if в многомерном массиве в Twig. Проверьте внутри цикла for, а затем оператор if.
Вот краткое описание этого с Twig:
{% for tag in tasks.tags if tag.id == '20' %}
here_if_true
{% endfor %}
---- ИЗМЕНИТЬ ----
ДЛЯ ELSE
Сделать else
. Итак, else
здесь, если ничего не найдено во всем for
:
{% for tag in tasks.tags %}
here_if_true
{% else %}
if there was nothing found
{% endfor %}
FOR-IF ELSE
Возможна комбинация if
и else
, но она не совпадает с if
else
внутри цикла for
. Поскольку else
для for
, а не для if
.
{% for tag in tasks.tags if tag.name == 'blue' %}
This will fire if in the FOR the tag.name that is blue
{% else %}
This will fire if there were NO tag.name blue were found ENTIRE FOR!
{% endfor %}
FOR-IF ELSE и ЕСЛИ ELSE
{% for tag in tasks.tags if tag.id == 3 %}
the id is 3
{% if tag.name == 'blue' %}
the id of the tag is 3 and tag.name is blue
{% else %}
the id of the tag is 3 but the tag.name is not blue
{% endif %}
{% else %}
there was no tag.id 3 found in the tasks.tags
{% endfor %}
Я нашел решение. Не ожидал, что это будет так просто. Иногда, я думаю, я просто пытаюсь сделать вещи слишком сложными.
{% for tag in tasks.tags %}
{% if tag.id == '20' %}
This tag has ID 20
{% endif %}
{% endfor %}
По-моему, это не самый эффективный способ, но он делает трюк для меня в данный момент.
Edit
Yenne Info подсказывала мне следующий метод. Это немного чище. Я не знаю, улучшает ли производительность.
{% for tag in tasks.tags if tag.id == '20' %}
Bingo! We've got a match
{% endfor %}
{% set flag = 0 %}
{% for tag in tasks.tags %}
{% if tag.id == "20" %}
{% set flag = 1 %}
{% endif %}
{% endfor %}
{% if flag == 1 %}
//do something
{% endif %}
Чтобы уменьшить код в ваших шаблонах, ветка имеет возможность создавать собственные фильтры. Для достижения более общей функциональности вы можете просто использовать имена переменных переменных и использовать имя атрибута в качестве другого параметра.
PHP
$filter = new Twig_SimpleFilter('inTags', function ($tags, $needle) {
$match = false;
foreach($tags as $tag){
if(in_array($needle, $tag)){
$match = true;
break;
}
}
return $match;
});
$twig = new Twig_Environment($loader);
$twig->addFilter($filter);
Twig
{% if tasks.tags|inTags(20) %}
//do something
{% endif %}
{% if myVar is xpath_aware('//tags/*[id=20]') %}
Если вы собираетесь делать условия на произвольном глубоком массиве, почему бы не использовать силу xpath
? Массив - это не более чем несериализованная XML-строка!
Итак, следующий массив:
$data = array(
'someKey' => 'someValue',
'foo' => 'bar',
'hello' => array(
'world' => true,
'tags' => array(
'0' => array(
'id' => '20',
'name' => 'someTag',
),
'1' => array(
'id' => '30',
'name' => 'someOtherTag',
),
),
),
);
Является эквивалентом строки XML (исправлено, чтобы избежать числовых тегов):
<data>
<someKey>someValue</someKey>
<foo>bar</foo>
<hello>
<world>1</world>
<tags>
<item0>
<id>20</id>
<name>someTag</name>
</item0>
<item1>
<id>30</id>
<name>someOtherTag</name>
</item1>
</tags>
</hello>
</data>
И вы хотите знать, соответствует ли ваш массив следующему выражению xpath:
//tags/*[id=20]
Мы создаем новый twig Test, который преобразует наш массив в объект SimpleXMLElement
и использует SimpleXMLElement::xpath()
, чтобы проверить соответствие данного xpath.
$test = new Twig_SimpleTest('xpath_aware', function (array $data, $path) {
$xml = new SimpleXMLElement('<?xml version="1.0"?><data></data>');
array_to_xml($data, $xml); // see full implementation below
return array() !== $xml->xpath($path);
});
Теперь мы можем запустить следующий тест в Twig:
{% if myVar is xpath_aware('//tags/*[id=20]') %}
Полная исполняемая реализация:
xpath_test.php
<?php
include (__DIR__.'/vendor/autoload.php');
$context = array(
'myVar' => array(
'someKey' => 'someValue',
'foo' => 'bar',
'hello' => array(
'world' => true,
'tags' => array(
'0' => array(
'id' => '20',
'name' => 'someTag',
),
'1' => array(
'id' => '30',
'name' => 'someOtherTag',
),
),
),
),
);
// http://stackoverflow.com/a/5965940/731138
function array_to_xml($data, &$xml_data)
{
foreach ($data as $key => $value) {
if (is_array($value)) {
if (is_numeric($key)) {
$key = 'item'.$key; //dealing with <0/>..<n/> issues
}
$subnode = $xml_data->addChild($key);
array_to_xml($value, $subnode);
} else {
$xml_data->addChild("$key", htmlspecialchars("$value"));
}
}
}
$twig = new Twig_Environment(new Twig_Loader_Array([]));
$test = new Twig_SimpleTest('xpath_aware', function (array $data, $path) {
$xml = new SimpleXMLElement('<?xml version="1.0"?><data></data>');
array_to_xml($data, $xml);
return array() !== $xml->xpath($path);
});
$twig->addTest($test);
$source = <<< EOT
{% if myVar is xpath_aware('//tags/*[id=20]') %}
It matches!
{% endif %}
EOT;
$template = $twig->createTemplate($source);
echo $template->display($context);
To run it
composer require twig/twig
php xpath_test.php