Подтвердить что ты не робот

Прокрутка по свойствам объекта

Я прочитал в документации Twig, что можно перебирать ассоциативный массив следующим образом:

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

Мне было интересно, возможно ли это для объектов типа stdClass. Я пробовал, и он не работает.

EDIT:
Я бы ожидал, что Twig будет перебирать значения свойств объекта, используя имена свойств в качестве ключей. Вместо этого блок команд, содержащийся в цикле for, вообще не выполняется.

4b9b3361

Ответ 1

Вы можете сначала передать объект в массив. Вы можете создать собственный фильтр, отбрасывающий ваш объект в массив. Подробнее о фильтрах можно найти здесь: http://twig.sensiolabs.org/doc/advanced.html#filters

Тогда он может выглядеть следующим образом:

{% for key, value in my_object|cast_to_array %}

Ответ 2

После загрузки 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 после Tadeck.:) Я уверен, что он не работает для какого-либо объекта 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.

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"
            }]
        }
    }
}

Twig

<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>

Ответ 3

Чтобы завершить ответ Тадека, вот как:

Если вы еще не создали или не установили расширение 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 %}

Готово, надеюсь, это поможет. От указателя Тадека.

Ответ 4

Я знаю, что это старый, но не

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

работает так же хорошо?

Ответ 5

Если это помогает кому-то другому. Вы можете заставить Twig перебирать свойства вашего объекта, если вы реализуете интерфейс PHP Iterator.

В моем случае у меня есть общий объект, который использует магические методы __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>