Як створити користувацький колектор даних

Дата оновлення перекладу 2023-06-22

Як створити користувацький колектор даних

Профілювальник Symfony отримує інформацію про профілювання та налагодження, використовуючи деякі спеціальні класи під назвою колектори даних. Symfony постачається з деякими з них, але ви можете також створити власні.

Створення користувацького колектора даних

Колектор даних - це PHP-клас, який реалізує DataCollectorInterface. Для зручності, ваші колектори даних також можуть розширюватися з класу DataCollector, який реалізує інтерфейс та надає деякі утиліти і властивість $this->data для зберігання зібраної інформації.

Наступний приклад демонструє користувацький колектор, який зберігає інформацію про запит:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/DataCollector/RequestCollector.php
namespace App\DataCollector;

use Symfony\Bundle\FrameworkBundle\DataCollector\AbstractDataCollector;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class RequestCollector extends AbstractDataCollector
{
    public function collect(Request $request, Response $response, \Throwable $exception = null)
    {
        $this->data = [
            'method' => $request->getMethod(),
            'acceptable_content_types' => $request->getAcceptableContentTypes(),
        ];
    }
}

Ось методи, які ви можете визначити у класі колектора даних:

Метод collect():

Зберагіє зібрані дані у локальних властивостях ($this->data якщо ви розширюєте з DataCollector). Якщо дані для збирання не можуть бути отримані через запит або відповідь, впровадьте необхідні сервіси у колектор даних.

Caution

Метод collect() викликається лише один раз. Він не використовується для "збирання" даних, але існує для "підбору" даних, які зберігаютья вашим сервісом.

Caution

Поки ваш профілювальник серіалізує екземпляри колекторів даних, вам не варто зберігати обʼєкти, які не можуть бути серіалізовані (на кшталт PDO обʼєктів) або вам потрібно надати ваш власний метод serialize().

Метод reset():
Викликається між запитами, щоб скинути стан профілювальника. Використайте його, щоб видалити всю зібрану методом collect() інформацію.
Метод getName():
Повертає ідентифікатор колектора, який повинен бути унікальним для додатку. Це значення використовується пізніше для доступу до інформації колектора (див. Як використовувати профілювальник у функціональному тесті), так що рекомендовано повертати короткий рядок у нижньому регістрі без пробілів.

Метод collect() викликається під час події kernel.response . Якщо вам потрібно зібрати дані, які доступні лише пізніше, реалізуйте LateDataCollectorInterface та визначіть метод lateCollect(), який викликається прямо перед серіалізацією даних профілювальника (під час події kernel.terminate ).

Note

Якщо ви використовуєте конфігурацію services.yaml за замовчуванням з autoconfigure, Symfony почне використовувати ваш колектор даних після наступного оновлення сторінки. Інакше, включіть колектор даних вручну .

Додавання шаблонів веб-профілювальника

Інформація, зібрана вашим колектором даних, може бути відображеня як у панелі існтрументів веб-налагодження, так і у веб-профілювальнику. Щоб зробити це, вам знадобиться створити шаблон Twig, який включає деякі конкретні блоки.

Спочатку, додайте метод getTemplate() у ваш клас колектора даних, щоб повернути шлях шаблону Twig для використання. Потім, доодайте деякі гетери, щоб дати шаблону доступ до зібраної інформації:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// src/DataCollector/RequestCollector.php
namespace App\DataCollector;

use Symfony\Bundle\FrameworkBundle\DataCollector\AbstractDataCollector;

class RequestCollector extends AbstractDataCollector
{
    // ...

    public static function getTemplate(): ?string
    {
        return 'data_collector/template.html.twig';
    }

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

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

У найпростішому випадку, вам просто потрібно відобразити інформацію у панелі інструментів, не надаючи панелі профілювальника. Це вимагає визначення блоку toolbar та установки значень двох змінних, під назвою icon і text:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{# templates/data_collector/template.html.twig #}
{% extends '@WebProfiler/Profiler/layout.html.twig' %}

{% block toolbar %}
    {% set icon %}
        {# це зміст, відображений як панель у панелі інстурментів #}
        <svg xmlns="http://www.w3.org/2000/svg"> ... </svg>
        <span class="sf-toolbar-value">Request</span>
    {% endset %}

    {% set text %}
        {# це зміст, відображений при наведенні курсору на панель
           панелі інструментів #}
        <div class="sf-toolbar-info-piece">
            <b>Method</b>
            <span>{{ collector.method }}</span>
        </div>

        <div class="sf-toolbar-info-piece">
            <b>Accepted content type</b>
            <span>{{ collector.acceptableContentTypes|join(', ') }}</span>
        </div>
    {% endset %}

    {# значення 'link', встановлене як 'false', означає, що ця панель не
       відображує розділу веб-профілювальнику #}
    {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: false }) }}
{% endblock %}

Tip

Вбудовані шаблони колекторів визначають всі свої зображення як вбудовані SVG-файли. Це дозволяє їм працювати всюди, без втручання у посилання веб-ресурсів:

1
2
3
4
{% set icon %}
    {{ include('data_collector/icon.svg') }}
    {# ... #}
{% endset %}

Якщо панель інструментів включає розширену інформацію веб-профілювальника, то шаблон Twig повинен також визначати доодаткові блоки:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{# templates/data_collector/template.html.twig #}
{% extends '@WebProfiler/Profiler/layout.html.twig' %}

{% block toolbar %}
    {% set icon %}
        {# ... #}
    {% endset %}

    {% set text %}
        <div class="sf-toolbar-info-piece">
            {# ... #}
        </div>
    {% endset %}

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

{% block head %}
    {# Опціонально. Тут ви можете послатися на або визначити власний зміст CSS і JS. #}
    {# Використайте {{ parent() }}, щоб розширити стилі за замовчуванням, замість їх перевизначення. #}
{% endblock %}

{% block menu %}
    {# Це меню зліва виникає при використанні профілювальника на весь екран. #}
    <span class="label">
        <span class="icon"><img src="..." alt=""/></span>
        <strong>Request</strong>
    </span>
{% endblock %}

{% block panel %}
    {# Опціонально, щоб відобразити якомога більше деталей. #}
    <h2>Acceptable Content Types</h2>
    <table>
        <tr>
            <th>Content Type</th>
        </tr>

        {% для типу в collector.acceptableContentTypes %}
        <tr>
            <td>{{ type }}</td>
        </tr>
        {% endfor %}
    </table>
{% endblock %}

Блоки menu і panel є єдиними обовʼязковими блоками для визначення змісту, відображеного в панелі веб-профілювальника, повʼязаного з цим колектором даних. Всі блоки мають доступ до обʼєкту collector.

Note

Позиція кожної панелі у панелі інструментів визначається пріорітетом колектора, який може бути визначений при конфігурації колектора даних вручну .

Note

Якщо ви використовуєте конфігурацію services.yaml за замовчуванням з autoconfigure, Symfony розпочне відображувати ваш колектор даних у панелі інструментів після наступного оновлення сторінки. Інакше, включіть колектор даних вручну .

Включення користувацьких колекторів даних

Якщо ви не використовуєте конфігурацію Symfony за замовчуванням з автомонтуванням та автоконфігурацією , вам знадобиться сконфігурувати колектор даних чітко:

1
2
3
4
5
6
7
8
9
10
11
12
# config/services.yaml
services:
    App\DataCollector\RequestCollector:
        tags:
            -
                name: data_collector
                # має співпадати зі значенням, поверрненим методом getName()
                id: 'App\DataCollector\RequestCollector'
                # необовʼязковий шаблон (має більший пріоритет ніж значення, повернене getTemplate())
                template: 'data_collector/template.html.twig'
                # необовʼязковий пріоритет (позитивне або відʼємне ціле число; за замовчуванням = 0)
                # priority: 300