我在 Twig 文档中读到,可以通过以下方式迭代关联数组:
{% for key, value in array %}
{{key}}
{{value}}
{% endfor %}
我想知道这是否也适用于 stdClass 类型的对象。
我本来希望 Twig 以属性名称作为键遍历对象的属性值。相反,for 循环中包含的指令块根本不执行。
您可以先将对象强制转换为数组。您可以构建自己的过滤器,将对象转换为数组。有关过滤器的更多信息,请访问:http://twig.sensiolabs.org/doc/advanced.html#filters
然后它可能看起来像这样:
{% for key, value in my_object|cast_to_array %}
要完成塔德克的回答,这里是如何:
如果您从未创建或设置 Twig 扩展(过滤器),则需要先按照此说明进行操作 http://symfony.com/doc/2.7/cookbook/templating/twig_extension.html
1) 添加到您的 AppBundle/Twig/AppExtension.php ('cast_to_array')
public function getFilters()
{
return array(
new 'Twig_SimpleFilter('md2html', array($this, 'markdownToHtml'), array('is_safe' => array('html'))),
new 'Twig_SimpleFilter('price', array($this, 'priceFilter')),
new 'Twig_SimpleFilter('cast_to_array', array($this, 'objectFilter')),
);
}
2) 添加到您的 AppBundle/Twig/AppExtension.php
public function objectFilter($stdClassObject) {
// Just typecast it to an array
$response = (array)$stdClassObject;
return $response;
}
3)在您的示例中.html.twig循环使用树枝和过滤器。
{% for key, value in row|cast_to_array %}
<td id="col" class="hidden-xs">{{ value }}</td>
{% endfor %}
完成,我希望它有所帮助。从塔德克的指点。
加载 TWIG 后,添加此过滤器:
$twig->addFilter( new Twig_SimpleFilter('cast_to_array', function ($stdClassObject) {
$response = array();
foreach ($stdClassObject as $key => $value) {
$response[] = array($key, $value);
}
return $response;
}));
它以塔德克的建议命名为cast_to_array。 :)我确定它不适用于任何类型的 stdClass 对象,但它确实解决了我打印 PHP 关联数组的问题:)按如下方式使用它:
{% for key, value in my_object|cast_to_array %}
<td>{{ value.1 }}</td>
{% endfor %}
支线故事
由于我经常进入这个 SO 页面,我认为展示我在哪里使用 Twig 迭代对象属性是相关的,因此它对有相同问题的其他人很有帮助:我试图从 .json 源打印一个表,但 PHP 的json_decode将任何"键":"值"转换为 PHP 关联数组,Twig 默认不打印该数组。因此,此过滤器剪切并提供供 Twig 使用的常规数组。
来源.json
{
"user": {
"family": {
"table": [{
"First_Name": "John",
"Last_Name": "Foo",
"Age": 25,
"Role": "Brother"
}, {
"First_Name": "Mary",
"Last_Name": "Bar",
"Age": 14,
"Role": "Sister"
}, {
"First_Name": "Joe",
"Last_Name": "Baz",
"Age": 33,
"Role": "Uncle"
}]
}
}
}
树枝
<table>
<thead>
<tr> {# get table headers from the table row #}
{% for row in user.family.table.0|cast_to_array %}
<th>{{ row.0 | replace({'_': ' '}) }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in user.family.table %}
<tr>
{% for key, value in row|cast_to_array %}
<td>{{ value.1 }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
这很旧,但不会
$assoc_array = json_decode(json_encode($stdClassObject), TRUE);
工作也一样?
以防这对其他人有帮助。 你可以让Twig迭代对象的属性,前提是你实现了PHP的迭代器接口。
就我而言,我有一个通用对象,它使用魔术方法__get(),__set(),__isset()和__unset(),同时将键值对存储在私有数组中。 这在 Twig 中工作正常,直到您想使用类似这样的东西迭代对象
<ul>
{% for prop, value in object %}
<li>{{prop|replace({'_': ' '})|title}}</li>
{% endfor %}
</ul>
为了使它工作,我必须实现迭代器接口。 然后上面的代码完美运行。
现在,由于神奇的 __get(),属性名称也不区分大小写,因此它们中的每一个都可以工作。
<ul>
{% for object in arrayOfObjects %}
<li>{{ object.property }}</li>
<li>{{ object.Property }}</li>
<li>{{ object.PROPERTY }}</li>
{% endfor %}
</ul>
{% for key, item in content.field_invoice_no if key|first != '#' %} <tr>
<td>{{ item }}</td>
<td> {{ content.field_invoice_date[key] }} </td>
<td> {{ content.field_invoice_price[key] }} </td>
</tr>
{% endfor %}
在键值上迭代对象
我终于想出了一个普通的 Twig 解决方案。我利用reduce过滤器将对象转换为数组。
假设我们从后端获取一个地址对象,并希望将其转换为关联数组,以便将每一行分开。
{% set address = { firstName: 'Stack', lastName: 'Overflow', address: 'here', zipCode: '1234' } %}
我们减少键并将它们添加到空数组中
{% set addressLines = address|keys|reduce((carry, key) => carry|merge({ (key): attribute(address, key) }), []) %}
这导致:
[ 'firstName' => 'Stack', 'lastName' => 'Overflow', 'address'=> 'here', 'zipCode' => '1234' ]
现在我们可以在 for 循环中渲染它
{% set allowedKeys = ['firstName', 'lastName', 'address'] %}
{% for key, line in addressLines|filter((v, k) => k in allowedKeys) %}
{{ line }}<br/>
{% endfor %}
将函数数组添加到 twing 并调用模板数组(值)
$loader = new 'Twig'Loader'FilesystemLoader('templates/'.$path);
$twig = new 'Twig'Environment($loader,['debug' => true]);
$function_2 = new 'Twig'TwigFunction('array', function ($value) {
return (array)$value;
});
$twig->addFunction($function_1);