Компонент VarDumper

Дата оновлення перекладу 2024-05-07

Компонент VarDumper

Компонент VarDumper надає механізми для вилучення стану з будь-якої змінної PHP. Так як він надбудовується, він надає покращену функцію dump(), яку ви можете використовувати замість var_dump.

Установка

1
$ composer require symfony/var-dumper --dev

Note

Якщо ви встановлюєте цей компонент поза додатком Symfony, вам потрібно підключити файл vendor/autoload.phpу вашому коді для включення механізму автозавантаження класів, наданих Composer. Детальніше можна прочитати у цій статті.

Note

Якщо ви використовуєте його всередині додатку Symfony, переконайтеся, що було встановлено DebugBundle (або запустіть composer require symfony/debug-bundle, щоб встановити його).

Функція dump()

Компонент VarDumper створює глобальну функцію dump(), яку ви можете використовувати замість, наприклад, var_dump. Використовуючи її ви отримуєте:

  • Спеціалізований перегляд по обʼєктах та джерелах, щоб, наприклад, відфільтрувати внутрішні обʼєкти Doctrine при скиданні однієї сутності проксі, або отримати більше інфорамції про відкриті за допомогою stream_get_meta_data файлу;
  • Конфігуровані формати виведення: виведення HTML або кольорового командного рядку;
  • Можилвість скидати внутрішні посилання, мʼякі (обʼєкти або джерела) або жорсткі (=& у властвостях масивів або обʼєктів). Повторна поява одного і того ж обʼєкта/ масиву/джерела не буде більше зʼявлятися знову і знову. Більш того, ви зможете дослідити структуру посилань ваших даних;
  • Можливість оперувати в контексті обробника буферизвції виведення.

Наприклад:

1
2
3
4
5
6
7
8
9
require __DIR__.'/vendor/autoload.php';

// створити змінну, яка може бути чим завгодно!
$someVar = ...;

dump($someVar);

// dump() повертає передане значення, щоб ви могли скинути обʼєкт та продовжувати використовувати його
dump($someObject)->someMethod();

За замовчуванням, формат виведення та напрямок обираються виходячи з вашого поточного PHP SAPI:

  • В командному рядку (CLI SAPI) виведення пишеться в STDOUT. Це може бути дивно для когось, так як це обходить механізм буферизації виведення PHP;
  • В інших SAPI, скибання пишуться у вигляді HTML у звичайному виведенні.

Tip

Ви також можете чітко обрати формат виведення, визначивши змінну середовища VAR_DUMPER_FORMAT та встановивши її значення як html, cli або серевер .

Note

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

Tip

Для того, щоб функція dump() завжди була доступна при виконанні будь-якого
PHP коду, ви можете встановити її на вашому компʼютері глобально:

  1. Запустіть composer global require symfony/var-dumper;
  2. Додайте auto_prepend_file = ${HOME}/.composer/vendor/autoload.php до вашого файлу php.ini;
  3. Іноді запускайте composer global update symfony/var-dumper, щоб мати останні виправлення багів.

Tip

Компонент VarDumper також надає функцію dd() ("dump and die" - "скинь та помри"). Ця функція відображає змінні, використовуючи dump() і одразу припиняє виконання скрипту (використовуючи функцію PHP exit).

Сервер скидань

Функція dump() виводить свій зміст в те ж вікно браузера або консольний термінал, що і ваш додаток. Іноді зміщення справжнього виведення з виведенням інформації налагодження може заплутати. Тому цей компонент надає сервер для збору всієї інформації налагодження.

Запустіть сервер командою server:dump і коли ви будете викликати dump(), інформація налагоджування не буде відображатися у потоці виведення, а відправиться на цей сервер, який відображатиме це у своїй консолі або HTML-файлі:

1
2
3
4
5
6
# відображає інформацію налагодження у консолі:
$ ./bin/console server:dump
  [OK] Server listening on tcp://0.0.0.0:9912

# зберігає інформацію налагодження у файлі, використовуючи формат HTML:
$ ./bin/console server:dump --format=html > dump.html

Всередині додатку Symfony, виведення сервера скидання налаштовується за допомогою опції dump_destination пакету debug:

1
2
3
# config/packages/debug.yaml
debug:
   dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"

Поза додатком Symfony використовуйте клас ServerDumper:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
use Symfony\Component\VarDumper\Dumper\ContextProvider\CliContextProvider;
use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider;
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
use Symfony\Component\VarDumper\Dumper\ServerDumper;
use Symfony\Component\VarDumper\VarDumper;

$cloner = new VarCloner();
$fallbackDumper = \in_array(\PHP_SAPI, ['cli', 'phpdbg']) ? new CliDumper() : new HtmlDumper();
$dumper = new ServerDumper('tcp://127.0.0.1:9912', $fallbackDumper, [
    'cli' => new CliContextProvider(),
    'source' => new SourceContextProvider(),
]);

VarDumper::setHandler(function (mixed $var) use ($cloner, $dumper): ?string {
    $dumper->dump($cloner->cloneVar($var));
});

Note

Другий аргумент ServerDumper - це екземпляр DataDumperInterface, що використовується як резервний, коли не можна досягти сервера. Третій аргумент - це постачальники контексту, які дозволяють збирати деяку інформацію про контекст в який було скинуто дані. Вбудований постачальники контексту - це cli, request та source.

Потімм ви можете використати наступну команду, щоб запустити готовий до використання сервер:

1
2
$ ./vendor/bin/var-dump-server
  [OK] Server listening on tcp://127.0.0.1:9912

Конфігурація сервера скидання зі змінними середовища

Якщо ви не хочете змінювати конфігурацію додатку (наприклад, щоб швидко налагодити проект, який вам дали), використайте змінну середовища VAR_DUMPER_FORMAT.

Спочатку, запустіть сервер як звичайно:

1
$ ./vendor/bin/var-dump-server

Потім виконайте ваш код зі змінною середовища VAR_DUMPER_FORMAT=server, сконфігурувавшиш це значення у файлі .env вашого додатку . Для команд консолі ви також можете визначити цю змінну середовища таким чином:

1
$ VAR_DUMPER_FORMAT=server [your-cli-command]

Note

Хостинг, використовуваний форматом server конфігурується у змінній середовища VAR_DUMPER_SERVER або 127.0.0.1:9912, якщо його не визначено. Якщо ви хочете, ви також можете сконфігурувати хостинг у змінній середовища VAR_DUMPER_FORMAT таким чином: VAR_DUMPER_FORMAT=tcp://127.0.0.1:1234.

Інтеграція DebugBundle та Twig

DebugBundle дозволяє більшу інтеграцію компонента у додатки Symfony.

Так як генерування виведення (навіть налагодження) у контролері або моделі вашого додатку може просто його зламати (наприклад, відправка HTTP-заголовків або порушення вашого перегляду), пакет конфігурує функцію dump(), щоб змінні скидалися у панелі інструментів веб-налагодження.

Але якщо панель інструментів не можна відобразити так як ви, наприклад, викликали die()/exit()/dd() або виникла фатальна помилка, тоді скидання пишуться у звичайному потоці виведення.

В шаблоні Twig доступні дві конструкції для скидання змінної. Вибір між ними в основному залежить від ваших особистих вподобань, і все ж:

  • {% dump foo.bar %} варто використовувати, коли початкове виведення шаблону не треба змінювати: змінні скидаються не вбудовано, а в панелі інструментів веб-налагодження;
  • і навпаки, {{ dump(foo.bar) }} скидає вбудовано і тому може підходити або не підходити у вашому випадку (наприклад, не варто використовувати його в атрибуті HTML або тезі <script>).

Цю поведінку моожна змінити, сконфігурувавши опцію debug.dump_destination. Прочитайте більше про це та інші опції в довіднику конфігурації DebugBundle.

Tip

Якщо скинутий зміст складний, розгляньте використання локального вікна пошуку, щоб знайти конкретні змінні або значення. Спочатку натисніть будь-де у скинутому змісті, а потім натисніть Ctrl. + F або Cmd. + F, щоб зʼявилося локальне вікно пошуку. Підтримуються всі розповсюджені скорочення для навігації по результатах (Ctrl. + G або Cmd. + G, F3, та ін.). Коли ви закінчите, натисніть Esc., щоб приховати вікно.

Якщо ви хочете використовувати введення пошуку вашого браузера, натисніть Ctrl. + F або Cmd. + F знову, фокусуючись на введенні пошуку VarDumper.

Використання компонента VarDumper у вашому наборі тестів PHPUnit

Компонент VarDumper надає a trait, який може допомогти написати деякі з ваших тестів для PHPUnit.

Це надасть вам два нових твердження:

assertDumpEquals()
веріфікує, щоб скидання змінної, надане в якості другого аругменту, відповідало очікуваному скиданню, наданому в якості першого аргументу.
assertDumpMatchesFormat()
такий же, як і попередній метод, але приймає заповнювачі у очікуваному скиданні, заснованому на методі assertStringMatchesFormat(), наданому PHPUnit.

VarDumperTestTrait також містить інші методи:

setUpVarDumper()
використовується для конфігурації доступних кастерів та їх опцій, що є способом лише контролю очікуваних вами полів та дозволяє писати лаконічні тести.
tearDownVarDumper()
викликається автоматично після кожного випадку, щоб скинути конфігурацію за замовчуванням, створену в setUpVarDumper().

Приклад:

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
use PHPUnit\Framework\TestCase;
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;

class ExampleTest extends TestCase
{
    use VarDumperTestTrait;

    protected function setUp(): void
    {
        $casters = [
            \DateTimeInterface::class => static function (\DateTimeInterface $date, array $a, Stub $stub): array {
                $stub->class = 'DateTime';
                return ['date' => $date->format('d/m/Y')];
            },
        ];

        $flags = CliDumper::DUMP_LIGHT_ARRAY | CliDumper::DUMP_COMMA_SEPARATOR;

        // цу конфігурує кастери та прапорці для використання у всіх тестах у цьому класі.
        // Якщо вам потрібні користувацькі конфігурації для кожного тесту окремо, а не для всього класу,
        // викличте натомість цей метод setUpVarDumper() з необхідних тестів.
        $this->setUpVarDumper($casters, $flags);
    }

    public function testWithDumpEquals(): void
    {
        $testedVar = [123, 'foo'];

        // очікуваний зміст скидання не має структури VarDumper за замовчуванням,
        // через користувацькі кастери та прапорці, використані в тесті
        $expectedDump = <<<EOTXT
[
  123,
  "foo",
]
EOTXT;

        // якщо перший аругмент - рядок, він має бути всіма очікуваним скиданням
        $this->assertDumpEquals($expectedDump, $testedVar);

        // якщо перший аргумент - не рядок, assertDumpEquals() скидає його та
        // співставляє зі скиданням другого аргументу
        $this->assertDumpEquals($testedVar, $testedVar);
    }
}

Приклади скидання та виведення

Для простих змінних, читання виведення має бути прямолінійним. Ось деякі приклади, що відображують першу змінну, визначену в PHP, а потім її представлення скидання:

1
2
3
4
5
6
7
8
$var = array(
    'a simple string' => "in an array of 5 elements",
    'a float' => 1.0,
    'an integer' => 1,
    'a boolean' => true,
    'an empty array' => array(),
);
dump($var);

Note

Сіра стрілка - це кнопка перемикача для відображення / приховування дітей вбудованих структур.

1
2
3
4
5
6
7
$var = "Це багаторядковий рядок.\n";
$var .= "Наведення на рядок відображає його довжину.\n";
$var .= "Дожвина UTF-8 рядків обчислюється в рамках символів UTF-8.\n";
$var .= "Довжина не-UTF-8 рядків обчислюється октетами.\n";
$var .= "Через це `\xE9` октет (\\xE9),\n";
$var .= "Цей рядок не є UTF-8 валідним, тому `b` prefix.\n";
dump($var);
1
2
3
4
5
6
7
8
9
class PropertyExample
{
    public string $publicProperty = 'The `+` prefix denotes public properties,';
    protected string $protectedProperty = '`#` protected ones and `-` private ones.';
    private string $privateProperty = 'Hovering a property shows a reminder.';
}

$var = new PropertyExample();
dump($var);

Note

`#14` - це внутрішній обʼєкт для обробки. Він дозволяє порівнювати два послідовних скидання одного і того ж обʼєкта.

1
2
3
4
5
6
7
8
class DynamicPropertyExample
{
    public string $declaredProperty = 'This property is declared in the class definition';
}

$var = new DynamicPropertyExample();
$var->undeclaredProperty = 'Runtime added dynamic properties have `"` around their name.';
dump($var);
1
2
3
4
5
6
7
class ReferenceExample
{
    public string $info = "Циклічні та споріднені посилання відображаються як `#number`.\n Наведення на них виділяє всі екземпляри в одному скиданні.\n";
}
$var = new ReferenceExample();
$var->aCircularReference = $var;
dump($var);
1
2
3
4
5
6
7
$var = new \ErrorException(
    "Для деяких обʼєктів властивості мають спеціальні значення,\n"
    ."які найкраще відображаються у вигляді обмежень, на кшталт\n"
    ."`severity` нижче. Наведення на них відображає значення (`2`).\n",
    E_WARNING
);
dump($var);
1
2
3
4
5
6
7
8
$var = array();
$var[0] = 1;
$var[1] =& $var[0];
$var[1] += 1;
$var[2] = array("Жорсткі посилання (циклічні або споріднені)");
$var[3] =& $var[2];
$var[3][] = "скидаються з використанням префіксів `&number`.";
dump($var);
1
2
3
4
5
$var = new \ArrayObject();
$var[] = "Деякі джерела та спеціальні обʼєкти, як поточний,";
$var[] = "іноді краще за все представити, використовуючи віртуальні";
$var[] = "властивості, що описують їх внутрішній стан.";
dump($var);
1
2
3
4
5
6
7
8
$var = new AcmeController(
    "Коли скидання перевищує максимальний ліміт обʼєктів\n"
    ."або коли зустрічаються спеціальні обʼєкти,\n"
    ."діти можуть бути замінені еліпсами та опціонально\n"
    ."мати число, яке повідомляє як і скільки було\n"
    ."видалено; В цьому випадку - `9`.\n"
);
dump($var);
1
2
3
4
5
6
7
8
9
class Foo
{
    // $foo не ініціалізовано, що не відрізняєтья від null
    private int|float $foo;
    public ?string $baz = null;
}

$var = new Foo();
dump($var);

Просунуте використання

Функція dump() - це просто тонка обгортка та більш зручний спосіб виклику VarDumper::dump(). Ви можете змінити поведінку цієї функції, викликавши VarDumper::setHandler($callable). Після цього виклики до dump() будуть перенаправлені $callable.

Додавши обробник, ви можете налаштувати Cloners, Dumpers та Casters, як пояснюється нижче. Просто реалізація функції обробника може виглядати так:

1
2
3
4
5
6
7
8
9
10
11
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
use Symfony\Component\VarDumper\VarDumper;

VarDumper::setHandler(function (mixed $var): ?string {
    $cloner = new VarCloner();
    $dumper = 'cli' === PHP_SAPI ? new CliDumper() : new HtmlDumper();

    return $dumper->dump($cloner->cloneVar($var));
});

Cloners

Клонувальник використовується для створення проміжного представлення будь-якої змінної PHP. Його виведення - це обʼєкт Data, який огортає це представлення.

Ви можете створити обʼєкт Data таким чином:

1
2
3
4
5
6
7
use Symfony\Component\VarDumper\Cloner\VarCloner;

$cloner = new VarCloner();
$data = $cloner->cloneVar($myVar);
// це потім часто передається дамперу
// див. приклад зверху цієї сторінки
// $dumper->dump($data);

Якою б не була структура клонованих даних, результуючі обʼєкти Data завжди можуть бути сериалізовані.

Клонувальник застосовує обмеження при створенні представлення так, щоб один міг предсавляти тільки підмножину клонованої змінної.
Перед викликом cloneVar(), ви можете сконфігурувати ці ообмеження:

setMaxItems()
Конфігурує максимальну кількість обʼєктів, які будуть клоновані поза мінімальної глибини вкладеності. Обʼєкти рахуються, використовуючи алгоритм пошуку вширину, щоб обʼєкти нижчого рівня мали вищий пріоритет, ніж глибоко вкладені обʼєкти. Вказання -1 скасовує обмеження.
setMinDepth()
Конфігурує мінімальну глибину дерева, де ми гарантовано клонуємо усі обʼєкти. Після досягнення цієї глибини, будуть клоновані лише обʼєкти setMaxItems. Значення за замовчуванням - 1, що відповідає старішим версіям Symfony.
setMaxString()
Конфігурує максимальну кількість символів, які будуть клоновані до обрізання занадто довгих рядків. Вказання -1 скасовує обмеження.

До скидання, ви можете ще більше обмежити результуючий обʼєкт Data, використовуючи наступні методи:

withMaxDepth()
Обмежує скидання у вимірі глибини.
withMaxItemsPerDepth()
Обмежує кількість обʼєктів для кожного рівня глибини.
withRefHandles()
Видаляє обробки внутрішніх обʼєктів для щільнішого виведення (корисно для тестів).
seek()
Обирає лише підчастини вже клонованих масивів, обʼєктів або джерел.

На відміну від попередніх обмежень клонувальників, які видаляють дані цілеспрямовано, ці можуть змінюватися туди і назад перед скиданням, так як вони не впливають на проміжне представлення внутрішньо.

Note

Якщо не застосовано жодного обмеження, обʼєкт Data такий само точний, як і нативна функція serialize, і тому його можна використати для цілей поза налагодженням.

Dumpers

Дампер відповідає за виведення представлення рядку змінної PHP, використовуючи обʼєкт Data як введення. Напрямок та форматування цього виведення відрізняється в різних дамперах.

Цей компонент постачається з HtmlDumper для HTML виведення та CliDumper для опціонально розфарбованого виведення командного рядку.

Напирклад, якщо ви хочете скинути якусь $variable, зробіть:

1
2
3
4
5
6
7
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;

$cloner = new VarCloner();
$dumper = new CliDumper();

$dumper->dump($cloner->cloneVar($variable));

Використовуючи перший аргумент конструктора, ви можете обрати потік виведення, де буде записано скидання. За замовчуванням, CliDumper пише у php://stdout, а HtmlDumper - у php://output. Але будь-який PHP-потік (джерело чи URL) прийнятний.

Замість напрямку потоку ви мтакож можете передати йому callable, яке буде повторно викликатися для кожного рядку, згенерованого дампером. Це викличне можна сконфігурувати, використовуючи перший аргумент конструктора дампера, а також використовуючи метод setOutput() або другий аргумент методу dump().

Наприклад, щоб отримати скидання у вигляді змінної рядку, ви можете:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;

$cloner = new VarCloner();
$dumper = new CliDumper();
$output = '';

$dumper->dump(
    $cloner->cloneVar($variable),
    function (int $line, int $depth) use (&$output): void {
        // Відʼємна глибина означає "кінець скидання"
        if ($depth >= 0) {
            // Додає відступ у два пробіли до рядку
            $output .= str_repeat('  ', $depth).$line."\n";
        }
    }
);

// $output тепер наповнено представленням скидання $variable

Інший варіант зробити те ж саме:

1
2
3
4
5
6
7
8
9
10
11
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;

$cloner = new VarCloner();
$dumper = new CliDumper();
$output = fopen('php://memory', 'r+b');

$dumper->dump($cloner->cloneVar($variable), $output);
$output = stream_get_contents($output, -1, 0);

// $output тепер наповнено представленням скидання $variable

Tip

Ви можете передати true другому арументу методу dump(), щоб змусити його повертати скидання у вигляді рядку:

1
$output = $dumper->dump($cloner->cloneVar($variable), true);

Дампери реалізують інтерфейс DataDumperInterface, який вказує метод dump(Data $data). Вони також зазвичай реалізують DumperInterface, який звільняє їх від повторнох реалізації логіки, необхідної для проходження внутрішньої структури обʼєкту Data.

HtmlDumper використовує темну тему за замовчуванням. Використайте метод setTheme(), щоб використовувати світлу тему:

1
2
// ...
$htmlDumper->setTheme('light');

HtmlDumper обмежує довжину рядку та глибину вкладення виведення, щоб зробити його більш читаним. Ці опції можна перевизначити третім опціональним параметром методу dump(Data $data):

1
2
3
4
5
6
7
8
9
10
use Symfony\Component\VarDumper\Dumper\HtmlDumper;

$output = fopen('php://memory', 'r+b');

$dumper = new HtmlDumper();
$dumper->dump($var, $output, [
    // 1 та 160 - значення за замовчуванням для цих опцій
    'maxDepth' => 1,
    'maxStringLength' => 160,
]);

Формат виведення дампера можна тонко налаштувати двома прапорцями: DUMP_STRING_LENGTH та DUMP_LIGHT_ARRAY, які передаються в якості
растрового зображення у третьому аргументі конструктора. Вони також можуть бути встановлені через змінні середовища за використання assertDumpEquals($dump, $data, $filter, $message) під час модульного тестування.

Аргумент $filter assertDumpEquals() може бути використано для передачі бітового поля констант Caster::EXCLUDE_* і впливає на очікуване виведення, зробленого різними кастерами.

Якщо встановлено DUMP_STRING_LENGTH, то довжина рядку відображається поруч з її змістом:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\AbstractDumper;
use Symfony\Component\VarDumper\Dumper\CliDumper;

$varCloner = new VarCloner();
$var = ['test'];

$dumper = new CliDumper();
echo $dumper->dump($varCloner->cloneVar($var), true);

// array:1 [
//   0 => "test"
// ]

$dumper = new CliDumper(null, null, AbstractDumper::DUMP_STRING_LENGTH);
echo $dumper->dump($varCloner->cloneVar($var), true);

// (додана довжина рядку перед рядком)
// array:1 [
//   0 => (4) "test"
// ]

Якщо встановлено DUMP_LIGHT_ARRAY, тоді масиви скидаються у скороченому форматі, схожому на коротку нотацію масивів PHP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\AbstractDumper;
use Symfony\Component\VarDumper\Dumper\CliDumper;

$varCloner = new VarCloner();
$var = ['test'];

$dumper = new CliDumper();
echo $dumper->dump($varCloner->cloneVar($var), true);

// array:1 [
//   0 => "test"
// ]

$dumper = new CliDumper(null, null, AbstractDumper::DUMP_LIGHT_ARRAY);
echo $dumper->dump($varCloner->cloneVar($var), true);

// (no more array:1 prefix)
// [
//   0 => "test"
// ]

Якщо ви хочете використати обидві опції, ви можете обʼєднати їх, використовуючи логічний оператор OR |:

1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\AbstractDumper;
use Symfony\Component\VarDumper\Dumper\CliDumper;

$varCloner = new VarCloner();
$var = ['test'];

$dumper = new CliDumper(null, null, AbstractDumper::DUMP_STRING_LENGTH | AbstractDumper::DUMP_LIGHT_ARRAY);
echo $dumper->dump($varCloner->cloneVar($var), true);

// [
//   0 => (4) "test"
// ]

Кастери

Обʼєкти та джерела, вкладені у змінну PHP "перетворюються" на масиви у проміжному представленні Data. Ви можете налаштувати представлення масиву длля кожного обʼєкту/джерела, підключивши кастер до цього процесу. Компонент вже містить багато кастерів для базових PHP-класів та інших розповсюджених класів.

Якщо ви хочете створити власний кастер, ви можете зареєструвати його перед клонуванням змінної PHP. Кастери реєструються використовуючи або конструктор клонувальника, або його метод addCasters():

1
2
3
4
5
6
7
8
use Symfony\Component\VarDumper\Cloner\VarCloner;

$myCasters = [...];
$cloner = new VarCloner($myCasters);

// або

$cloner->addCasters($myCasters);

Наданий аргумент $myCasters - це масив, який відображає клас, інтерфейс або тип джерела викличному:

1
2
3
4
$myCasters = [
    'FooClass' => $myFooClassCallableCaster,
    ':bar resource' => $myBarResourceCallableCaster,
];

Як ви можете помітити, типи джерел мають префікс :, щоб уникнути зіткнення з імʼям класу.

Так як обʼєкт має один основний клас і потенційно багато батьківських класів або інтерфейсів, багато кастерів може бути застосовано до одного обʼєкту. У цьому випадку, кастери викликаються один за одним, починаючи з кастерів, привʼязаних до інтерфейсів, батьківських класів а потім до основного класу. Декілька кастерів також можуть бути зареєстровані для одного типу/класу/інтерфейсу джерела. Вони викликаються у порядку реєстрації.

Кастери відповідають за повернення властивостей обʼєкту або джерела, яке клонується у масиві. Це викличні, які приймають пʼять аргументів:

  • обʼєкт або джерело, яке створюється;
  • масив, змодельований для обʼєктів піся нативного оператору створення PHP (array);
  • обʼєкт Stub, який представляє основні властивості обʼєкта (клас, тип і т.д.);
  • true/false в залежності від того, чи вкладено викликаний кастер у структуру;
  • Бітове поле констант Caster ::EXCLUDE_*.

Ось простий кастер, який нічого не робить:

1
2
3
4
5
6
7
8
use Symfony\Component\VarDumper\Cloner\Stub;

function myCaster(mixed $object, array $array, Stub $stub, bool $isNested, int $filter): array
{
    // ... наповнити/змінити $array за вашими потребами

    return $array;
}

Для обʼєктів, параметр $array постачається попередньо наповненим, використовуючи нативний оператор створення PHP (array) або зі зворотним значенням $object->__debugInfo(), якщо існує магічний метод. Потім, зворотне значення одного кастера надаєтья як аргумент масиву іншому кастеру у ланцюжку.

При створенні з оператором (array), префікси PHP захищають властивості з \0*\0, а приватні - з класом, який володіє властивістю. Наприклад, \0Foobar\0 буде префіксом для всіх приватних властивостей обʼєктів типу Foobar. Кастери дотримуються цієї угоди та додають ще два префікси: \0~\0 використовується для віртуальних властивостей, а
\0+\0 - для динамічних (додані властивості рантайму не в оголошенні класу).

Note

Хоча ви і можете, рекомендовано не змінювати стан обʼєкта під час його створення у кастері.

Tip

До написання ваших власних кастерів, вам варто перевірити вже існуючі.

Додавання семантики з метаданими

Так як кастери підключаються до конкретних класів або інтерфейсів, вони знають про обʼєкти, які вони змінюють. Змінивши обʼєкт $stub (третій аргумент будь-якого кастера), можна передати ці знання результуючому обʼєкту Data, тобто, дамперам. Щоб допомогти вам зробити це (дивіться початковий код, щоб побачити, як це працює), компонент постачаєтья з набором обгорток для розповсюдженої додаткової семантики. Ви можете використати:

  • ConstStub, щоб огорнути значення, яке представлене константою PHP;
  • ClassStub, щоб огорнути ідентифікатор PHP (тобто імʼя класу чи методу, інтерфейс і т.д.);
  • CutStub, щоб замінити великі шумні обʼєкти /рядки/тощо на еліпси;
  • CutArrayStub, щоб залишити тільки деякі корисні ключі масиву;
  • ImgStub, щоб огорнути зображення;
  • EnumStub, щоб огорнути набір віртуальних значень (тобто значень, які не існують як властивості в оригінальній структурі даних PHP, але які варто зазначити поруч з реальними);
  • LinkStub, щоб огорнути рядки, які можуть бути перетворені на посилання дамперами;
  • TraceStub та їх родичі
  • FrameStub і
  • ArgsStub, щоб огорнути сліди PHP (використовується ExceptionCaster).

Наприклад, якщо ви знаєте, що ваші обʼєкти Product мають властивість brochure, яка містить імʼя файлу або URL, ви можете огорнути їх у LinkStub, щоб вказати HtmlDumper зробити їх клікабельними:

1
2
3
4
5
6
7
8
9
use Symfony\Component\VarDumper\Caster\LinkStub;
use Symfony\Component\VarDumper\Cloner\Stub;

function ProductCaster(Product $object, array $array, Stub $stub, bool $isNested, int $filter = 0): array
{
    $array['brochure'] = new LinkStub($array['brochure']);

    return $array;
}