web-dev-qa-db-ja.com

Twigオブジェクトのプロパティを反復処理する

Twigのドキュメントを読んで、次の方法で連想配列を反復処理できることがわかりました。

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

タイプstdClassのオブジェクトでもこれが可能かどうか疑問に思っていました。

Twigプロパティ名をキーとしてオブジェクトのプロパティ値を反復処理することを期待していました。代わりに、forループに含まれる命令ブロックはまったく実行されません。

23
Bogdan

最初にオブジェクトを配列にキャストできます。オブジェクトを配列にキャストする独自のフィルターを作成できます。フィルターの詳細については、こちらをご覧ください: http://twig.sensiolabs.org/doc/advanced.html#filters

その場合、次のようになります。

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

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オブジェクトでも機能しないことは確かですが、印刷の問題は必ず解決しましたPHP連想配列:)次のように使用します:

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

サイドストーリー

このSOページにたくさん入ったので、私はTwig foriterating overを使用している場所を示すことが適切だと思うオブジェクトのプロパティ、それは同じ問題を抱えている他の人々に役立ちます:.jsonソースからテーブルを印刷しようとしましたが、PHPのjson_decodeはany "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"
            }]
        }
    }
}

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>
8
roberto.cr

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ループで、twigとフィルターを使用します。

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

完了しました。タデックのポインターから。

6
Dung

これが他の人に役立つ場合。 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>
2
kbull

私はこれが古いことを知っていますが、そうではないでしょう

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

同様に動作しますか?

2
Guest9000000