PHP 8.4 Requirements
Symfony 8.0 требует PHP 8.4+. Это первая мажорная версия, использующая возможности PHP 8.4.
Новые возможности PHP, используемые в Sf8
| Возможность | Версия PHP | Использование в Symfony |
|---|---|---|
| Readonly properties | 8.1 | DTOs, Value Objects |
| Enums | 8.1 | Statuses, Types в формах |
| Fibers | 8.1 | Асинхронные компоненты |
| Readonly classes | 8.2 | Immutable DTO |
#[\Override] |
8.3 | Переопределение методов |
| Property hooks | 8.4 | Validated properties |
| Asymmetric visibility | 8.4 | public private(set) |
<?php
declare(strict_types=1);
namespace App\Entity;
// PHP 8.4: Property hooks
final class Product
{
public string $name {
set(string $value) {
if (strlen($value) < 3) {
throw new \InvalidArgumentException('Name too short');
}
$this->name = trim($value);
}
}
// PHP 8.4: Asymmetric visibility
public private(set) int $viewCount = 0;
public function incrementViews(): void
{
$this->viewCount++;
}
}
<?php
declare(strict_types=1);
namespace App\DTO;
// PHP 8.2: Readonly class
final readonly class CreateUserDTO
{
public function __construct(
public string $email,
public string $name,
public string $password,
) {
}
}
Breaking Changes: Sf7.4 -> Sf8.0
Symfony 8.0 -- мажорная версия. Все deprecated из Sf7.x удалены.
Удалённые deprecated
Security
<?php
// REMOVED: Old Guard authenticator
// Symfony\Component\Security\Guard\AuthenticatorInterface -- REMOVED
// USE: New authenticator system
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
# REMOVED: anonymous configuration
security:
firewalls:
main:
anonymous: true # REMOVED in Sf8
# USE: PUBLIC_ACCESS in access_control
security:
firewalls:
main:
lazy: true
access_control:
- { path: ^/public, roles: PUBLIC_ACCESS }
Routing
<?php
// REMOVED: Annotations
// use Symfony\Component\Routing\Annotation\Route; -- REMOVED
// USE: PHP Attributes
use Symfony\Component\Routing\Attribute\Route;
#[Route('/api/users', name: 'api_users')]
final class UserController
{
// ...
}
Forms
<?php
// REMOVED: getBlockPrefix() default behavior changed
// Type names are now fully qualified class names by default
// REMOVED: Various deprecated form options
// 'allow_extra_fields' option in resolver -- behavior changed
DependencyInjection
<?php
// REMOVED: ContainerAwareInterface
// use Symfony\Component\DependencyInjection\ContainerAwareInterface; -- REMOVED
// USE: Constructor injection
final class MyService
{
public function __construct(
private readonly SomeDependency $dependency,
) {
}
}
# REMOVED: XML/annotations for service configuration
# All services configured via YAML or PHP attributes only
HttpKernel
<?php
// REMOVED: Various deprecated event names
// use Symfony\Component\HttpKernel\Event\GetResponseEvent; -- REMOVED
// USE: Symfony\Component\HttpKernel\Event\RequestEvent
// REMOVED: Deprecated controller resolver methods
Изменения поведения
1. Конфигурация: только YAML и PHP
# Sf7.4: XML, YAML, PHP, Annotations supported
# Sf8.0: Only YAML and PHP attributes
# routes/routes.yaml -- OK
# routes/routes.xml -- NO LONGER SUPPORTED for exam
# @Route annotation -- NO LONGER SUPPORTED
2. Default autoconfigure: true
В Sf8 autoconfigure включено по умолчанию для всех сервисов. Ранее нужно было явно указывать.
3. Error handling
<?php
// Sf8: handle_all_throwables enabled by default
// All errors (including PHP errors) converted to exceptions
Новые возможности Symfony 8.0
1. #[MapRequestPayload] и #[MapQueryString]
<?php
declare(strict_types=1);
namespace App\Controller;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use Symfony\Component\HttpKernel\Attribute\MapQueryString;
final class ApiController extends AbstractController
{
// Automatically deserialize JSON body to DTO
#[Route('/api/users', methods: ['POST'])]
public function create(
#[MapRequestPayload] CreateUserDTO $dto,
): JsonResponse {
// $dto is validated and populated from request body
return new JsonResponse(['id' => 1], 201);
}
// Automatically map query parameters to DTO
#[Route('/api/users', methods: ['GET'])]
public function list(
#[MapQueryString] UserFilterDTO $filter,
): JsonResponse {
// $filter populated from ?page=1&limit=20&sort=name
return new JsonResponse([]);
}
}
2. Console PHP attributes
<?php
declare(strict_types=1);
namespace App\Command;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Attribute\Argument;
use Symfony\Component\Console\Attribute\Option;
#[AsCommand(name: 'app:greet')]
final class GreetCommand extends Command
{
// New in Sf8: define args via attributes
#[Argument(description: 'Who to greet')]
private string $name;
#[Option(shortcut: 'u', description: 'Uppercase output')]
private bool $uppercase = false;
protected function execute(InputInterface $input, OutputInterface $output): int
{
$text = "Hello, {$this->name}!";
$output->writeln($this->uppercase ? strtoupper($text) : $text);
return Command::SUCCESS;
}
}
3. Service Locators и #[AutowireLocator]
<?php
declare(strict_types=1);
namespace App\Service;
use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
final class HandlerDispatcher
{
public function __construct(
#[AutowireLocator([
'create' => CreateHandler::class,
'update' => UpdateHandler::class,
'delete' => DeleteHandler::class,
])]
private readonly ContainerInterface $handlers,
) {
}
}
4. Clock Component
<?php
declare(strict_types=1);
use Symfony\Component\Clock\ClockInterface;
final class TokenGenerator
{
public function __construct(
private readonly ClockInterface $clock,
) {
}
public function generate(): Token
{
return new Token(
value: bin2hex(random_bytes(32)),
expiresAt: $this->clock->now()->modify('+1 hour'),
);
}
}
5. Messenger как отдельная тема
В Sf7.4 Messenger был частью Miscellaneous. В Sf8 -- полноценная тема с транспортами, middleware, retry strategy.
Миграция с 7.4 на 8.0: ключевые шаги
| Шаг | Действие |
|---|---|
| 1 | Обновить PHP до 8.4+ |
| 2 | Исправить все deprecation warnings в Sf7.4 |
| 3 | Заменить аннотации на PHP-атрибуты |
| 4 | Удалить XML-конфигурацию, перевести на YAML |
| 5 | Обновить Security: новая система authenticators |
| 6 | Удалить использование ContainerAwareInterface |
| 7 | Обновить composer.json до symfony/*: ^8.0 |
| 8 | Запустить тесты, исправить ошибки |
Проверка deprecations
# Run tests with deprecation detection
SYMFONY_DEPRECATIONS_HELPER=max[total]=0 php bin/phpunit
# Show all deprecations
php bin/console debug:container --deprecations
Итоги
- Sf8.0 требует PHP 8.4+ (property hooks, asymmetric visibility)
- Все deprecated из Sf7.x удалены (Guard, аннотации, XML)
- Только YAML и PHP-атрибуты для конфигурации
- Новые возможности: #[MapRequestPayload], Console attributes, Clock
- Service Locators (#[AutowireLocator]) -- новая тема DI
- Messenger выделен в отдельную тему экзамена
- Миграция: исправить все deprecated в 7.4, затем обновить до 8.0