Вышли новые версии Symfony 6.4 и 7.0
Вышла очередная минорная версия Symfony 6.4 и полноценная версия Symfony 7.0.
Как и все минорные обновления Symfony поддерживает обратную совместимость.
А это означает, что вы сможете легко обновиться, ничего не меняя в своем коде.
В Symfony 7.0 некоторые старые функции были удалены из проекта.
Ниже перечислены основные изменения для этих новых версий:
Command Profiler
Профайлер Symfony — одна из любимых функций Symfony для большинства разработчиков. Он собирает всю информацию о HTTP-запросах, чтобы вы могли проверять эти данные при отладке проблем. В Symfony 6.4 и 7.0 был улучшен профилировщик, чтобы также можно было профилировать консольные команды .
Для этого добавьте --profile
опцию (которая автоматически определяется Symfony во всех командах, включая вашу) при запуске любой команды:
php bin/console --profile app:my-command
Профилировщик команд включает в себя такую информацию, как:
- Полная входная информация об аргументах/опциях и конфигурация сервера, такая как переменные среды;
- Общее время выполнения и потребление памяти, включая подробную трассировку каждого события и запуска прослушивателя/подписчика;
- Подробная информация о вызванных и невызванных слушателях;
- Сообщения журнала и сообщения об устаревании, созданные во время выполнения команды;
- Все остальные панели, с которыми вы знакомы, например, запросы Doctrine, отправленные электронные письма и т. д.
FQCN-based Routes
В приложениях Symfony система маршрутизации требует, чтобы каждый маршрут имел имя, которое представляет собой произвольную строку, однозначно идентифицирующую маршрут. Это имя позже используется, например, при создании URL-адресов из определений маршрутов.
Имя маршрута обычно определяется явно разработчиками при добавлении маршрутов (например, с помощью name
параметра атрибута #[Route]
):
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
final class BlogController extends AbstractController
{
#[Route('/blog', name: 'blog_index')]
public function index(): Response
{
// ...
}
}
Если вы не определяете имя маршрута явно, Symfony генерирует автоматическое имя маршрута на основе FQCN (полного имени класса) контроллера и имени метода действия. В приведенном выше примере имя автоматического маршрута будет app_blog_index
.
Автоматические имена маршрутов работают, поскольку комбинация полного доменного имени контроллера и имени метода действия гарантированно будет уникальной в приложении. Вот почему в Symfony 6.4 улучшали эту функцию, чтобы ввести автоматические маршруты на основе FQCN контроллера.
Если метод контроллера связан с одним маршрутом (помните, что Symfony позволяет связать один и тот же метод контроллера с несколькими маршрутами), Symfony создаст псевдоним маршрута по шаблону <Controller FQCN>::<method name>
.
В предыдущем примере index()
метод связан как с явным blog_index
именем маршрута, так и с App\Controller\BlogController::index
именем маршрута, автоматически созданным Symfony:
use App\Controller\BlogController;
// ...
// генерация урла с использованием названия маршрута
$url = $this->urlGenerator->generate('blog_index');
// генерация урла на основе полного имени класса FQCN
$url = $this->urlGenerator->generate(BlogController::class . '::index');
Если вы используете вызываемые контроллеры, которые представляют собой классы контроллеров, определяющие магический метод PHP __invoke()
, псевдоним маршрута становится еще проще, поскольку вам не нужно добавлять имя метода:
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/blog', name: 'blog_index')]
final class BlogController extends AbstractController
{
public function __invoke(): Response
{
// ...
}
}
URL-адрес, указывающий на этот метод, может быть сгенерирован с blog_index
явным именем маршрута и BlogController::class
псевдонимом маршрута.
DatePoint
В Symfony 6.2 был представлен компонент Clock
, чтобы улучшить тестируемость вашего кода, чувствительного ко времени. В Symfony 6.4 представлен DatePoint
новый класс даты/времени PHP, который легко интегрируется с компонентом Clock
.
Основное преимущество DatePoint
перед PHP DateTime
заключается в том, что для установки текущего времени DateTimeImmutable
используются глобальные статические часы компонента Clock
. Это означает, что если вы внесли какие-либо изменения в часы, это отразится при создании новых DatePoint
экземпляров:
use Symfony\Component\Clock\DatePoint;
// получение текущего времени установленного в компоненте Clock
$createdAt = new DatePoint();
Класс DatePoint
расширяется DateTimeImmutable
, поэтому вы можете использовать его в своем коде где DateTimeImmutable
угодно DateTimeInterface
. DatePoint
также включает некоторые утилиты для обработки значений даты/времени, но не предназначен для замены сторонних библиотек, которые предоставляют множество утилит для работы со значениями даты/времени:
// set the current time explicitly
$firstPublicCommitOfSymfony = new DatePoint('2005-10-18 16:27:36 Europe/Paris');
// use current Clock time but specify a timezone
$orderCreatedAt = new DatePoint(timezone: new \DateTimezone('UTC'));
// use an existing date as the reference to create a DatePoint
$welcomeDiscountValidUntil = new DatePoint('+1 month', reference: $user->getSignedUpAt());
Еще одним улучшением класса DatePoint
является то, что ошибки (например, создание недопустимых дат или попытка внести недопустимые изменения даты) больше не возвращаются, false
а выдают ошибку \DateMalformedStringException
. Это исключение было введено в PHP 8.3, но благодаря Symfony PHP 8.3 вы можете использовать его, начиная с PHP 7.1.
Таким образом, DatePoint
это полная замена классов даты и времени PHP, которая обеспечивает полную интеграцию с Clock
компонентом, некоторыми утилитами и улучшенной обработкой ошибок.
Simpler Logout
В приложениях Symfony функция выхода из системы безопасности включена и настраивается для каждого брандмауэра. Вы можете настроить его с помощью YAML, XML или PHP, но в следующем примере показана только конфигурация YAML:
# config/packages/security.yaml
security:
# ...
firewalls:
main:
# ...
logout:
path: app_logout
Ключом этой конфигурации является path
опция, определяющая маршрут/URL-адрес, который пользователю необходимо просмотреть, чтобы фактически отказаться от аутентификации в приложении. Symfony полностью обрабатывает этот процесс выхода из системы, но этот маршрут/URL-адрес должен существовать в вашем приложении.
Вот почему вам необходимо добавить этот маршрут в свое приложение. Например, вы можете создать следующее определение маршрута YAML, которое не указывает ни на какое действие контроллера:
# config/routes.yaml
app_logout:
path: /logout
methods: GET
Или, если вы предпочитаете определять все маршруты в классах PHP через атрибуты, вы можете сделать это:
// src/Controller/SecurityController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
class SecurityController extends AbstractController
{
#[Route('/logout', name: 'app_logout', methods: ['GET'])]
public function logout(): never
{
// controller can be blank: it will never be called!
throw new \Exception('Don\'t forget to activate logout in security.yaml');
}
}
Создание этого маршрута всегда казалось немного необычным. Если Symfony обрабатывает всю логику выхода из системы, почему бы не позаботиться и об этом маршруте? В Symfony 6.4 была упрощана функция выхода из системы.
Технически это работает благодаря настраиваемому загрузчику маршрутов, который создает для вас маршруты выхода из системы. Если ваше приложение использует Symfony Flex, необходимая конфигурация будет добавлена в ваше приложение автоматически при обновлении symfony/security-bundle
рецепта. В противном случае вам нужно будет добавить эту конфигурацию в свое приложение:
# config/routes/security.yaml
_security_logout:
resource: security.route_loader.logout
type: service
AssetMapper Improvements
AssetMapper был представлен в Symfony 6.3 как новый и современный способ управления ресурсами JavaScript и CSS без необходимости сборки или внешних зависимостей, таких как Node. В Symfony 6.4 этот компонент был улучшен, был добавлен ряд функций. Теперь компонент также стабилен.
В Symfony 6.4 при запуске importmap:require
файл всегда загружается локально. Файлы загружаются в assets/vendor/
каталог, который по умолчанию игнорируется в .gitignore
.
php bin/console importmap:install
В Symfony 6.4 теперь вы можете импортировать файлы CSS из файлов JavaScript:
// assets/app.js
import './styles/app.css';
Для сторонних CSS-файлов вы можете использовать importmap:require
команду:
php bin/console importmap:require bootstrap/dist/css/bootstrap.min.css
Затем импортируйте его:
// assets/app.js
import 'bootstrap/dist/css/bootstrap.min.css';
В Symfony 6.4 при вызове {{ importmap('app') }}
AssetMapper найдет все файлы JavaScript, которые app.js
импортируются (рекурсивно), и предварительно загрузит их. Это означает, что каждый файл JavaScript, необходимый для запуска вашего кода, будет предварительно загружен без каких-либо дополнительных действий.
В Symfony 6.4, если вы устанавливаете компонент symfony/web-link
, AssetMapper автоматически добавит Link
заголовки к вашему ответу, которые сообщают браузеру предварительно загрузить все файлы CSS, которые в конечном итоге будут отображены с помощью {{ importmap() }}
функции.
AssetMapper не требует этапа сборки, но он все равно просматривает ваши файлы CSS и JavaScript в поисках импортируемых файлов. AssetMapper всегда имел внутренний кеш, чтобы не делать этого при каждом запросе. Но в Symfony 6.4 это было значительно улучшено за счет устранения необходимости сканирования файлов, отличных от CSS и JavaScript. Изображения, шрифты и т. д. теперь обслуживаются напрямую, без каких-либо накладных расходов во время разработки или во время работы asset-map:compile
.
Ссылка на источник: https://symfony.com/blog/symfony-7-0-0-released