如何检查多维 Twig 数组的值?
How to check a multidimensional Twig array for values?
要简单地检查数组是否包含某个值,我会这样做:
{% 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']
是否具有标签 ID 20。我希望我不会因为使用 PHP 数组格式而让您感到困惑。
我找到了解决方案。没想到这么简单。有时我想我只是想把事情弄得太复杂。
{% for tag in tasks.tags %}
{% if tag.id == '20' %}
This tag has ID 20
{% endif %}
{% endfor %}
在我看来,这不是最有效的方法,但它目前对我有用。
编辑
Yenne Info 告诉我以下方法。它有点干净。我不知道它是否提高了性能。
{% for tag in tasks.tags if tag.id == '20' %}
Bingo! We've got a match
{% endfor %}
这个更像是一个多维循环,以备不时之需
{% for animals in array %}
{% set dogs = animals.dogs %}
{% for dog in dogs %}
{{ dump(dog.type) }}
{% endfor%}
{% endfor %}
设置标志并使用循环。之后你可以在 if 条件下使用标志。
{% set flag = 0 %}
{% for tag in tasks.tags %}
{% if tag.id == "20" %}
{% set flag = 1 %}
{% endif %}
{% endfor %}
{{ flag }}
在 Twig 中设置标志
{% set flag = 0 %}
{% for tag in tasks.tags %}
{% if tag.id == "20" %}
{% set flag = 1 %}
{% endif %}
{% endfor %}
{% if flag == 1 %}
//do something
{% endif %}
在 PHP
中创建 Custom Filter
为了减少模板中的代码,twig 有机会创建自定义过滤器。要实现更通用的功能,您可以简单地使用变量名称并将属性名称用作另一个参数。
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);
树枝
{% 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 that will convert our array into a SimpleXMLElement
object, and use 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',
),
),
),
),
);
//
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);
给运行吧
composer require twig/twig
php xpath_test.php
对于 Twig 中多维数组中的 if 语句。检查 for 循环,然后检查 if 语句。
这是 Twig 的 shorthand:
{% for tag in tasks.tags if tag.id == '20' %}
here_if_true
{% endfor %}
----编辑----
其他
做一个else
。所以这里的else
就是如果整个for
:
什么都找不到
{% for tag in tasks.tags %}
here_if_true
{% else %}
if there was nothing found
{% endfor %}
FOR-IF ELSE
可以组合 if
和 else
,但这与 for
循环中的 if
else
不同.因为 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 和 IF 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 %}
要简单地检查数组是否包含某个值,我会这样做:
{% 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']
是否具有标签 ID 20。我希望我不会因为使用 PHP 数组格式而让您感到困惑。
我找到了解决方案。没想到这么简单。有时我想我只是想把事情弄得太复杂。
{% for tag in tasks.tags %}
{% if tag.id == '20' %}
This tag has ID 20
{% endif %}
{% endfor %}
在我看来,这不是最有效的方法,但它目前对我有用。
编辑
Yenne Info 告诉我以下方法。它有点干净。我不知道它是否提高了性能。
{% for tag in tasks.tags if tag.id == '20' %}
Bingo! We've got a match
{% endfor %}
这个更像是一个多维循环,以备不时之需
{% for animals in array %}
{% set dogs = animals.dogs %}
{% for dog in dogs %}
{{ dump(dog.type) }}
{% endfor%}
{% endfor %}
设置标志并使用循环。之后你可以在 if 条件下使用标志。
{% set flag = 0 %}
{% for tag in tasks.tags %}
{% if tag.id == "20" %}
{% set flag = 1 %}
{% endif %}
{% endfor %}
{{ flag }}
在 Twig 中设置标志
{% set flag = 0 %}
{% for tag in tasks.tags %}
{% if tag.id == "20" %}
{% set flag = 1 %}
{% endif %}
{% endfor %}
{% if flag == 1 %}
//do something
{% endif %}
在 PHP
中创建 Custom Filter为了减少模板中的代码,twig 有机会创建自定义过滤器。要实现更通用的功能,您可以简单地使用变量名称并将属性名称用作另一个参数。
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);
树枝
{% 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 that will convert our array into a SimpleXMLElement
object, and use 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',
),
),
),
),
);
//
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);
给运行吧
composer require twig/twig
php xpath_test.php
对于 Twig 中多维数组中的 if 语句。检查 for 循环,然后检查 if 语句。
这是 Twig 的 shorthand:
{% for tag in tasks.tags if tag.id == '20' %}
here_if_true
{% endfor %}
----编辑----
其他
做一个else
。所以这里的else
就是如果整个for
:
{% for tag in tasks.tags %}
here_if_true
{% else %}
if there was nothing found
{% endfor %}
FOR-IF ELSE
可以组合 if
和 else
,但这与 for
循环中的 if
else
不同.因为 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 和 IF 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 %}