Загрузка...

PSR без боли: что реально важно в 2025-2026 году

От логирования до HTTP-клиентов — обзор того, что реально используется в коде каждый день.
php

Введение: когда PHP повзрослел

Когда-то PHP был как подросток без режима дня — каждый писал, как хотел. Кто-то называл классы MyClass, кто-то my_class, а кто-то просто файлы с функциями пихал в /includes.
В 2009-м появился PHP-FIG (Framework Interop Group) — ребята из мира фреймворков (Symfony, Laravel, Zend, etc.), которые сказали:

«Давайте хоть как-то договоримся, чтобы наши библиотеки могли дружить».

Так родились PSR — PHP Standards Recommendations.
Не RFC, не законы, но стандарты, которые формируют “единый язык” между библиотеками и фреймворками.


Что сейчас актуально?

На момент 2025 года активно используются PSR-1, 2, 3, 4, 6, 7, 11, 12, 13, 14, 15, 17, 18, 19 и 20.
Некоторые устарели (например, PSR-0), но их дух живёт в новых версиях.
Давай разберёмся по-человечески, что они делают и зачем.


🧱 Базовые стандарты

PSR-1: Basic Coding Standard

Минимальные правила, чтобы код выглядел похоже.

  • Классы — StudlyCaps (UserController),
  • Методы — camelCase (getUserById),
  • Константы — UPPER_SNAKE_CASE,
  • Один класс = один файл.

Это просто “договорённость, чтобы глаза не кровили”.
💡 Технически: многие анализаторы (PHP_CodeSniffer, PHPStan) опираются на PSR-1 для базовых проверок.


PSR-12: Extended Coding Style

Наследник PSR-2, который добавил современности (short arrays, strict_types, nullable types).
Это стиль форматирования: где ставить фигурные скобки, как делать отступы, пробелы и т.д.

Пример:

declare(strict_types=1);

namespace App\Services;

use App\Models\User;

class UserService
{
    public function findUser(int $id): ?User
    {
        return User::find($id);
    }
}

💡 Если используешь Laravel Pint или PHP-CS-Fixer — они под капотом следуют PSR-12.


⚙️ Автозагрузка и структура

PSR-4: Autoloading Standard

Самый важный стандарт, без которого Composer не был бы тем, чем он есть.

Идея: пространство имён (namespace) = путь к файлу.

namespace App\Services;

class EmailSender {}

→ файл лежит по пути /src/Services/EmailSender.php.

💡 PSR-4 полностью заменил старый PSR-0.
Благодаря ему ты просто пишешь composer dump-autoload — и всё работает магией.


🧩 Взаимодействие между компонентами

PSR-3: Logger Interface

Единый интерфейс для логирования.
Неважно, Monolog или собственный логгер — если реализует Psr\Log\LoggerInterface, он совместим.

use Psr\Log\LoggerInterface;

class UserService {
    public function __construct(private LoggerInterface $logger) {}

    public function registerUser(array $data) {
        $this->logger->info('User registered', $data);
    }
}

💡 Laravel, Symfony, Slim, Monolog — все используют PSR-3.


PSR-11: Container Interface

Контейнер зависимостей с двумя методами:

$container->get('logger');
$container->has('logger');

Это базовый контракт для DI-контейнеров.
Laravel, Symfony, PHP-DI — все могут быть подменяемы, если следуют PSR-11.


Для REST-API, где ссылки внутри данных — часть контракта.
Определяет интерфейсы для ссылок (LinkInterface) и коллекций ссылок (LinkProviderInterface).
💡 Реже встречается, но важен для HAL/JSON-LD API.


PSR-14: Event Dispatcher

Единый способ отправлять и слушать события:

$dispatcher->dispatch(new UserRegisteredEvent($user));

События — объекты, слушатели — обработчики.
Это слабое связывание между модулями (чистая архитектура рулит).


🌐 HTTP и middleware

PSR-7: HTTP Message Interfaces

Определяет интерфейсы для HTTP-запросов и ответов.
Фреймворки теперь говорят на одном языке:

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

💡 Symfony, Slim, Laravel (через bridges) — все поддерживают PSR-7.


PSR-15: HTTP Middleware

Определяет контракт для middleware:

interface MiddlewareInterface {
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface;
}

То есть ты можешь использовать middleware из любого фреймворка — оно просто работает.


PSR-17: HTTP Factories

Раньше у PSR-7 была проблема: как создавать объекты Request/Response, если интерфейс не говорит об этом.
PSR-17 добавил фабрики:

$request = $factory->createServerRequest('GET', '/users');
$response = $factory->createResponse(200);

PSR-18: HTTP Client

Интерфейс для HTTP-клиентов.
Теперь можно подменять Guzzle, Symfony HttpClient, Buzz — всё совместимо, если реализует Psr\Http\Client\ClientInterface.

$response = $client->sendRequest($request);

🧠 Новое поколение

PSR-19: PHPDoc Tags

Новый стандарт оформления аннотаций PHPDoc.
Упорядочивает то, как писать @param, @return, @throws.
Важен для IDE, статического анализа и автогенерации API.


PSR-20: Clock Interface

Свежий, но мощный.
Добавляет интерфейс Psr\Clock\ClockInterface:

interface ClockInterface {
    public function now(): DateTimeImmutable;
}

Зачем?
Чтобы тестировать код, зависящий от времени. Можно подменять “время” в тестах или моках.


🧩 Итоговая картина

Категория PSR Назначение
Код-стиль PSR-1, PSR-12 Единый вид кода
Автозагрузка PSR-4 Подключение классов
Логирование PSR-3 Общий интерфейс логгера
DI-контейнер PSR-11 Контракт контейнера
HTTP PSR-7, 15, 17, 18 Единые запросы, middleware и клиенты
События PSR-14 Диспетчер событий
Докблоки PSR-19 Формат PHPDoc
Время PSR-20 Единый интерфейс для часов
Гипермедиа PSR-13 Ссылки и HATEOAS

Заключение: зачем это всё?

PSR — это не “правила ради правил”.
Это мост между библиотеками и фреймворками, благодаря которому можно свободно комбинировать пакеты без боли и костылей.

Если твой код совместим с PSR — он, как LEGO: всё щёлкает и собирается без напильника.
И в этом — взросление PHP.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *