Новое в Symfony 6.3 — Улучшения DX (Часть 3)

Источник: «New in Symfony 6.3: DX Improvements (Part 3)»
Symfony 6.3 улучшает ограничение Cascade, позволяя обрезать XML параметры, устанавливать службы в тестовом контейнере и улучшает обработку сигналов Console.

Разрешено исключать свойства в ограничение Cascade

Ограничение Cascade используется для проверки всего класса, включая все объекты, которые могут храниться в его свойствах.

// src/Model/BookCollection.php
namespace App\Model;

use App\Model\Author;
use App\Model\BookMetadata;
use Symfony\Component\Validator\Constraints as Assert;

#[Assert\Cascade(exclude: ['metadata', 'author'])]
class BookCollection
{
#[Assert\NotBlank]
protected $name = '';

public BookMetadata $metadata;

public Author $author;

// ...
}

Разрешено обрезать параметры XML

При использовании XML для настройки сервис контейнера вы не можете задать такие параметры:

<parameter key="app.admin_email">
something@example.com
</parameter>

Symfony не обрезает содержимое XML, поэтому значение параметра app.admin_email будет \n something@example.com\n. В Symfony 6.3 мы добавили новую опцию trim для XML конфигурации:

<parameter key="app.admin_email" trim="true">
something@example.com
</parameter>

Значение параметра app.admin_email теперь будет something@example.com.

Разрешена настройка приватных сервисов в тестовом контейнере

Хорошо известная методика когда тестирование сервисов в приложениях Symfony состоит в том, чтобы имитировать зависимость некоторых тестируемых сервисов. Чтобы это сработало, необходимо установить эти сервисы как публичные в тестовом контейнере:

# config/services_test.yaml
services:
# переопределите алиас таким, каким он должен быть, делая его публичным
App\Contracts\Repository\NewsRepositoryInterface:
alias: App\Repository\NewsRepository
public: true

В Symfony 6.3 мы улучшаем эту функцию, чтобы вы могли устанавливать приватные сервисы прямо в сервис контейнере, без необходимости делать какие-либо сервисы публичными. Например, в своих тестах вы можете использовать такой код, чтобы напрямую установить фиктивный/мок сервис:

static::getContainer()->set('example.client', new MockHttpClient(...));

DomCrawler обновление метода innerText()

Компонент DowCrawler определяет метод innerText() для возврата текста, который является прямым потомком текущего узла, исключая текст из дочерних узлов. В Symfony 6.3 мы несколько улучшили его:

// если контекст '<p>Foo <span>Bar</span> Baz</p>', то сейчас innerText()
// возвращает текст только первого узла 'Foo' вместо 'Foo Baz'
$text = $crawler->filterXPath('//body/p')->innerText();

// innerText() по умолчанию обрезает пробельные символы, но вы можете получить
// не изменённый текст, передав FALSE в качестве аргумента
$text = $crawler->filterXPath('//body/p')->innerText(false);

Управление кодом выхода при обработке сигналов консоли

В Symfony 6.3 мы внесли некоторые изменения в логику обработки сигналов. Во-первых, мы выходим по умолчанию (чтобы имитировать поведение PHP) только в SIGINT и SIGTERM. Во-вторых, теперь вы можете сообщить через консольное событие о выходе с помощью пользовательского кода (благодаря новому методу $event->setExitCode($code);).

Наконец, внутри консольного события вы можете предотвратить команду выхода:

use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleSignalEvent;

$dispatcher->addListener(ConsoleEvents::SIGNAL, function (ConsoleSignalEvent $event) {
// ...

$event->abortExit();
});

Дополнительные материалы

Предыдущая Статья

Руководство по замыканиям и стрелочным функциям в PHP

Следующая Статья

Обработка исключений в Laravel: советы и рекомендации