Symfony2の本番環境のTwig内で変数の中身を綺麗に表示（pretty print）したい

## Why

* 開発時のデバッグ目的なら`dump`でよい
    * See: [dump - Documentation - Twig - The flexible, fast, and secure PHP template engine](http://twig.sensiolabs.org/doc/functions/dump.html)
* しかし管理ツールのような用途で、複雑な配列の変数の中身を綺麗に表示したい要件があった

## 結論

* 設定次第では本番環境でも`dump`を有効にできるが、デバッグ目的の趣が強いのであまりおすすめできない気がする
* 代わりに`json_encode`を`JSON_PRETTY_PRINT`と`JSON_UNESCAPED_UNICODE`オプション付きで使えばわりと綺麗に表示できる
* bootstrap3を使うなら下記のイメージ

```jinja
<pre><code>
    {{- var|json_encode(constant('JSON_PRETTY_PRINT') b-or constant('JSON_UNESCAPED_UNICODE')) -}}
</code></pre>
```

## 検証その1

* 下記のようなコントローラーとテンプレートを用意し、開発環境と本番環境での表示を確認する
* Symfony2のバージョンは

```
$ ./app/console --version
Symfony version 2.7.7 - app/dev/debug
```

### コントローラー

```php
<?php
// (namespace など省略)
class PrettyPrintController extends Controller
{
    /**
     * @Route("/")
     * @Template
     */
    public function indexAction()
    {
        return [
            'var' => [
                0,
                '1',
                true,
                null,
                [
                    'key' => 'value',
                ],
            ],
        ];
    }
}
```

### テンプレート（Twig）

```jinja
{% extends 'base.html.twig' %}

{% block stylesheets %}
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
{% endblock %}

{% block body %}
  <div class="container">
    <h2>dump</h2>
    <div>
      {{ dump(var) }}
    </div>

    <h2>json_encode</h2>
    <pre><code>
    {{- var|json_encode(constant('JSON_PRETTY_PRINT') b-or constant('JSON_UNESCAPED_UNICODE')) -}}
    </code></pre>
  </div>
{% endblock %}
```

### 開発環境（`environment: dev`）での表示

![](https://qiita-image-store.s3.amazonaws.com/0/17168/5da98016-c643-aee5-f4ea-4e437143f0ca.png)

* `dump`では綺麗な表示に加えて、JavaScriptを使った変数の中身の開閉処理機能がある
* `json_encode`でも綺麗に表示できている

### 本番環境（`environment: prod`）での表示

* 下記のようなエラーが出て表示できない

```
[2015-12-19 16:36:19] request.CRITICAL: Uncaught PHP Exception Twig_Error_Syntax: "Unknown "dump" function in ...
```

## 検証その2

* 本番環境でも`dump`できるように設定を変えて、本番環境での表示を確認する

### `app/config/config.yml`

* `twig.debug` の値を `kernel.debug` の値に影響されず、常に`true`を返すようにする

```diff
--- a/app/config/config.yml
+++ b/app/config/config.yml
@@ -33,7 +33,7 @@ framework:

 # Twig Configuration
 twig:
-    debug:            "%kernel.debug%"
+    debug:            true
     strict_variables: "%kernel.debug%"

 # Assetic Configuration
```

### `app/config/services.yml`

* `twig.extension` タグを付けた `Twig_Extension_Debug` のサービスを追加する

```diff
--- a/app/config/services.yml
+++ b/app/config/services.yml
@@ -7,3 +7,7 @@ services:
 #    service_name:
 #        class: AppBundle\Directory\ClassName
 #        arguments: ["@another_service_name", "plain_value", "%parameter_name%"]
+    my.twig.extension.debug:
+        class: Twig_Extension_Debug
+        tags:
+            - { name: 'twig.extension' }
```

### 本番環境（`environment: prod`）での表示

![](https://qiita-image-store.s3.amazonaws.com/0/17168/26b0c9c7-fd40-e986-6a5f-e0e999dac013.png)

* 本番環境でも `dump` が表示された
* しかし、上述した開発環境で表示された形式になっていない
    * JavaScriptを使った変数の中身の開閉処理機能が**ない**
* この理由はTwigの`dump`関数で処理されているコードが別だから
    * 開発環境の方は `DebugBundle` が有効なので、`VarDumper` コンポーネントで処理されている
        * See: http://symfony.com/doc/current/components/var_dumper/introduction.html#debugbundle-and-twig-integration
    * 一方、本番環境では `DebugBundle` を有効にしていないので `Twig_Extension_Debug` で処理されている

## 参考

* [php - How to use dump in TWIG? - Stack Overflow](http://stackoverflow.com/questions/10120256/how-to-use-dump-in-twig)