Utilisation de la barre de debug de symfony

Pour profiter de la toute nouvelle barre de debug de Symfony dans Phyxo, je vais en profiter pour afficher les requêtes SQL. Il suffit de suivre la documentation du Data Collector

Il faut créer une classe qui implémente l'interface DataCollectorInterface ou qui entend la classe DataCollector. Je vais choisir la deuxième option. Il faut définir les méthodes collect, reset et getName. L'abstraction de base de données DBLayer gère déjà la collecte des requêtes effectuées. Il suffit de récupérer cette information. Pour récupérer cette information, il suffit d'injecter la connexion à la base de données via le constructeur. Le code correspondant est alors :

class DBLayerCollector extends DataCollector
{
    public function __construct(DBLayer $conn)
    {
        $this->conn = $conn;
    }

    public function collect(Request $request, Response $response, \Exception $exception = null)
    {
        $queries = $this->conn->getQueries();

        $this->data = [
            'queries' => $queries,
            'time' => array_sum(array_column($queries, 'time')) * 1000 // in milliseconds
        ];
    }

    public function getQueries()
    {
        return $this->data['queries'];
    }

    public function getTime()
    {
        return $this->data['time'];
    }

    public function reset()
    {
        $this->data = [];
    }

    public function getName()
    {
        return 'app.dblayer_collector';
    }
}

Ensuite, il faut créer le template qui permet de gérer l'affichage dans la barre de debug via le bloc toolbar mais aussi dans le profiler via le bloc menu. Ce template hérite de @WebProfiler/Profiler/layout.html.twig et ça donne ça :

{% extends '@WebProfiler/Profiler/layout.html.twig' %}

{% block toolbar %}
     {% set icon %}
        <svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
            <path fill="#AAAAAA" d="M5,8h14c1.7,0,3-1.3,3-3s-1.3-3-3-3H5C3.3,2,2,3.3,2,5S3.3,8,5,8z M18,3.6c0.8,0,1.5,0.7,1.5,1.5S18.8,6.6,18,6.6s-1.5-0.7-1.5-1.5S17.2,3.6,18,3.6z M19,9H5c-1.7,0-3,1.3-3,3s1.3,3,3,3h14c1.7,0,3-1.3,3-3S20.7,9,19,9z M18,13.6
    c-0.8,0-1.5-0.7-1.5-1.5s0.7-1.5,1.5-1.5s1.5,0.7,1.5,1.5S18.8,13.6,18,13.6z M19,16H5c-1.7,0-3,1.3-3,3s1.3,3,3,3h14c1.7,0,3-1.3,3-3S20.7,16,19,16z M18,20.6c-0.8,0-1.5-0.7-1.5-1.5s0.7-1.5,1.5-1.5s1.5,0.7,1.5,1.5S18.8,20.6,18,20.6z"></path>
        </svg>
        <span class="sf-toolbar-value">{{collector.queries|length}}</span>
        <span class="sf-toolbar-info-piece-additional-detail">
            <span class="sf-toolbar-label">in</span>
            <span class="sf-toolbar-value">{{collector.time|number_format(2)}}</span>
            <span class="sf-toolbar-label">ms</span>
        </span>
    {% endset %}

    {% set text %}
        <div class="sf-toolbar-info-piece">
            <b>Database Queries</b>
            <span class="sf-toolbar-status">{{collector.queries|length}}</span>
        </div>
        <div class="sf-toolbar-info-piece">
            <b>Total queries time</b>
            <span>{{collector.time|number_format(2)}}ms</span>
        </div>
    {% endset %}

    {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { 'link': true }) }}
{% endblock %}

{% block menu %}
    <span class="label">
        <span class="icon">
            <svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
                <path fill="#AAAAAA" d="M5,8h14c1.7,0,3-1.3,3-3s-1.3-3-3-3H5C3.3,2,2,3.3,2,5S3.3,8,5,8z M18,3.6c0.8,0,1.5,0.7,1.5,1.5S18.8,6.6,18,6.6s-1.5-0.7-1.5-1.5S17.2,3.6,18,3.6z M19,9H5c-1.7,0-3,1.3-3,3s1.3,3,3,3h14c1.7,0,3-1.3,3-3S20.7,9,19,9z M18,13.6
    c-0.8,0-1.5-0.7-1.5-1.5s0.7-1.5,1.5-1.5s1.5,0.7,1.5,1.5S18.8,13.6,18,13.6z M19,16H5c-1.7,0-3,1.3-3,3s1.3,3,3,3h14c1.7,0,3-1.3,3-3S20.7,16,19,16z M18,20.6c-0.8,0-1.5-0.7-1.5-1.5s0.7-1.5,1.5-1.5s1.5,0.7,1.5,1.5S18.8,20.6,18,20.6z"></path>
            </svg>
        </span>
        <strong>Queries</strong>
    </span>
{% endblock %}

{% block panel %}
    <h2>Queries</h2>

    <p>Database queries: {{collector.queries|length}}</p>
    <p>Total time: {{collector.time|number_format(2)}}ms</p>

    <table>
        <thead>
            <tr>
                <th>Query</th>
                <th>Time</th>
                <th>Rows</th>
            </tr>
        </thead>
        <tbody>
        {% for query in collector.queries %}
            <tr>
                <td>{{query.sql|raw}}</td>
                <td>{{(query.time * 1000)|number_format(2)}}ms</td>
                <td>{{query.rows}}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
{% endblock %}

Il ne reste plus à définir le service dans config/services.yaml :

App\DataCollector\DBLayerCollector:
      tags:
        -
          name: data_collector
          template: 'data_collector/queries.html.twig'
          id: 'app.dblayer_collector'
          public: false

Comme d'habitude, le commit correspondant se trouve sur le dépôt de Phyxo. Et ça donne ça :

datacollector queries

Haut de page