26

我在 Twig 文档中读到,可以通过以下方式迭代关联数组:

{% for key, value in array %}  
 {{key}}  
 {{value}}  
{% endfor %}  

我想知道这是否也适用于 stdClass 类型的对象。

我本来希望 Twig 以属性名称作为键来迭代对象的属性值。相反,for循环中包含的指令块根本不执行。

4

7 回答 7

21

您可以先将对象转换为数组。您可以构建自己的过滤器,将您的对象转换为数组。更多关于过滤器的信息在这里:http ://twig.sensiolabs.org/doc/advanced.html#filters

然后它可能看起来像这样:

{% for key, value in my_object|cast_to_array %}
于 2012-08-07T08:30:54.403 回答
9

要完成 Tadeck 的回答,方法如下:

如果您从未创建或设置过 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)在您的 example.html.twig 循环中使用树枝和过滤器。

{% for key, value in row|cast_to_array %}
       <td id="col" class="hidden-xs">{{ value }}</td>
{% endfor %}

完成了,希望对你有帮助。从塔德克的指针。

于 2015-12-21T18:36:22.033 回答
8

加载 TWIG 后,添加此过滤器:

$twig->addFilter( new Twig_SimpleFilter('cast_to_array', function ($stdClassObject) {
    $response = array();
    foreach ($stdClassObject as $key => $value) {
        $response[] = array($key, $value);
    }
    return $response;
}));

根据Tadeck的建议,它被命名为cast_to_array。:) 我确定它不适用于任何类型的stdClass Object,但它确实解决了我打印 PHP关联数组的问题:) 按如下方式使用它:

{% for key, value in my_object|cast_to_array %}
    <td>{{ value.1 }}</td>
{% endfor %}

番外篇

因为我经常进入这个 SO 页面,所以我认为显示我在哪里使用 Twig迭代对象属性是相关的,所以它对其他有同样问题的人很有帮助:我试图从 .json 打印一个表源,但 PHP 的 json_decode 将任何"key" : "value"转换为 PHP 关联数组,Twig 默认不打印。所以这个过滤器切割并提供一个规则数组供 Twig 使用。

source.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>
于 2013-06-25T20:00:32.237 回答
6

我知道这是旧的,但不会

$assoc_array = json_decode(json_encode($stdClassObject), TRUE);

工作也一样吗?

于 2017-12-01T19:45:00.637 回答
4

以防这对其他人有帮助。如果你实现了 PHP 的 Iterator 接口,你可以让 Twig 迭代你的对象的属性。

在我的例子中,我有一个通用对象,它使用魔术方法 __get()、__set()、__isset() 和 __unset(),同时将键值对存储在私有数组中。这在 Twig 中工作正常,直到您想使用类似这样的方法迭代对象

<ul>
{% for prop, value in object %}
    <li>{{prop|replace({'_': ' '})|title}}</li>
{% endfor %}
</ul>

为了使它工作,我必须实现 Iterator 接口。然后上面的代码完美运行。

现在由于神奇的 __get() 属性名称也不区分大小写,因此每个这些都可以工作。

<ul>
{% for object in arrayOfObjects %}
    <li>{{ object.property }}</li>
    <li>{{ object.Property }}</li>
    <li>{{ object.PROPERTY }}</li>
{% endfor %}
</ul>
于 2013-11-06T00:10:51.593 回答
0
  {% 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 %}

在键值上迭代对象

于 2021-03-11T12:24:50.240 回答
0

我终于想出了一个香草 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 %}
于 2021-05-10T10:58:24.767 回答