Обновить
8K+

Symfony *

Свободный фреймворк, написанный на PHP5

8,45
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Современный API Reference в Symfony через Scalar

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели7.4K

Работая с PHP, испытываешь постоянную необходимость поддерживать документацию в актуальном состоянии. В последнее время PHP проекты — это API‑first, когда бек на PHP, а фронт собирается отдельно.

Тут у нас два пути:

— Spec‑first, то есть сначала готовится спецификация всех возможных маршрутов с входными/выходными параметрами, ошибками и пр. Часто это YAML‑файл OpenAPI.

— OpenAPI файл генерируется на основе атрибутов и аннотаций в коде.

В первом случае мы делаем то, что прописано в спецификации и имеем возможность сравнить, верно ли у нас всё сделано. Во втором случае у нас всегда актуальная схема (после автоматического обновления).

Хотелось бы легкий, современный UI для отрисовки готового OpenAPI yaml файла для первого типа работы с документацией API.
И, кажется, Scalar для этого отлично подходит, но вот интеграции из коробки у Symfony со Scalar нет. В одном своём проекте у меня подход OpenAPI‑first, то есть сначала спецификация, потом реализация. Мощный NelmioApiDocBundle тянуть в проект не хотелось.

Выбор пал на Scalar. Но одно плохо, нет интеграции. Можно было просто интегрировать своими силами в проекте, но понял, что можно оформить это в виде bundle и в дальнейшем переиспользовать в других проектах.

Читать далее

Новости

Как загрузить файл через JSON-RPC, если в JSON нет типа для файла

Уровень сложностиСредний
Время на прочтение4 мин
Охват и читатели5.2K

В JSON нет типа для файла - так как же загрузить файл через JSON-RPC? Разбираю, как это устроено в otezvikentiy/json-rpc-api 5.2: multipart как транспортный адаптер, валидация через Assert\File, честно про CSRF. И историю о том, как эту фичу принёс внешний контрибьютор.

Читать статью

ИИ-картограф: как карты сшиваются в бесшовный мир — тулсеты (toolsets) для MMORPG игр на PHP, ч. 21

Уровень сложностиПростой
Время на прочтение8 мин
Охват и читатели8.8K

Я сшил разрозненные карты MMO в один бесшовный мир: игрок выходит из города в пустыню и не замечает, что под ним уже работает другой сервер. А всю рутину картографа — импорт, разметку препятствий, разрезание карт и проверку связей — отдаю ИИ. Заодно проверил, что происходит, если доверить ему игровую графику

Читать далее

Symfony JSON-RPC API Bundle три года спустя: что боевая эксплуатация сделала с кодом

Уровень сложностиСредний
Время на прочтение5 мин
Охват и читатели5.4K

В августе 2023-го я писал здесь про свой бандл для JSON-RPC API на Symfony. С тех пор он дорос с 1.x до 5.1 и работает в нескольких продакшенах - от финтех-инструментов до HRM-системы. Честный отчёт: 17 найденных отклонений от спецификации, приватные поля, утекавшие в ответы, CORS-заголовок через запятую - и что из этих уроков стало фичами бандла.

Читать далее

Каталог ассетов и git для MMO: как командой вести игру в облаке — создание сервера для онлайн ММО игр на PHP, ч. 19

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели12K

Над одной игрой работает команда: люди правят контент в браузере, ИИ — через тот же сервис, локально разворачивать ничего не нужно. Каждый ассет живёт своим git-репозиторием: это и бэкап, и способ собрать игру из готовых анимаций, карт и библиотек — а перед тем как правки уедут в мир, видно построчно, что именно уйдёт.

Читать далее

Кэширование в Symfony: мы сломали авторизацию и исправили это с помощью Lock

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели8K

Мы добавили кэширование, чтобы ускорить работу бэкэнда.

Затем кэширование нарушило авторизацию.

Поначалу ситуация казалась безобидной. Сервису Symfony требовался JWT-токен для взаимодействия с внешним API. Запрос нового токена перед каждым вызовом был неэффективным, поэтому мы сохранили его в кэше и использовали повторно.

При нормальной нагрузке все работало.

При нагрузочном тестировании токен истекал, и несколько запросов одновременно проходили через один и тот же поток. Каждый из них видел пустой кэш и запрашивал у внешнего API новый JWT. Внешний API аннулировал предыдущий токен каждый раз, когда выдавал новый.

После этого часть приложения начала работать с уже недействительными токенами.

Решение заключалось не только в использовании общего Memcached, ведь проблема была не в хранилище, а в праве на обновление общего состояния.

В статье история о том, как мы с командой обнаружили состояние гонки, что изменил Kubernetes в этой проблеме и почему Symfony Lock с повторной проверкой кэша стал недостающей частью архитектуры.

Читать далее

ч. 18 — Конвейер контента для MMO: импорт анимации, экипировка и обновление игры без патчей

Уровень сложностиПростой
Время на прочтение5 мин
Охват и читатели13K

ИИ сегодня умеет рисовать персонажей и делать для них анимации. Но это только половина задачи. Их ещё нужно встроить в игру: импортировать, связать с игровой логикой, привязать экипировку, разместить в мире и доставить игрокам без обновления клиента. В этой части показываю, как этот конвейер работает у меня.

Читать далее

Что будет, если убрать из ORM предположение «одна таблица — одна entity»?

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели9.4K

Большинство ORM строятся вокруг естественного предположения: одной таблице соответствует одна entity. Это настолько привычно, что даже не обращаешь внимания.

Это не правило, но вокруг него проектируются почти все остальные механизмы: метаданные принадлежат классу, Unit of Work отслеживает экземпляры этого класса, миграции собираются из его описания, а объектная модель постепенно начинает повторять структуру базы данных.

Но часто в коде не требуется вся таблица, многие поля служат только конкретным процессам и ни читать, ни менять эти поля в других процессах не требуется. В статье посмотрим два подхода работы с сущностями. А также к чему я пришёл, попробовав сделать по‑другому.

Читать далее

Как связать symfony 8 и Angular 22?

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели7.9K

Именно так я думал, когда начинал разбираться в этой теме. Но, разобравшись, я с уверенностью могу сказать, что это реально, такая идея имеет место быть и обслуживать такую архитектуру легко.

В данной статье будет описан процесс реализации архитектуры веб‑приложения с удобной системой докер контейнеров. Здесь не будет обсуждаться CI/CD, исключительно development‑side процесса разработки.

Я использую самый свежий на момент написания PHPStorm 2026.1.4 от Jetbrains, но абсолютно не важно какой IDE вы пользуетесь. В теории можно и в блокноте писать хороший код.

Читать далее

LLM говнокодит не хуже людей. Только быстрее

Время на прочтение14 мин
Охват и читатели17K

Полгода назад я начал писать пет-проект практически полностью с помощью LLM-агентов. Первые недели это был чистый дофамин: фичи вылетали за вечер, я один успевал столько, сколько раньше делала небольшая команда. А потом всё начало вязнуть — ровно так, как вязнет любой проект с говнокодом: каждая новая фича ломала две старые, агент правил код «на ощупь», а я тратил время не на продукт, а на разгребание.

Под катом — что я понял и что в итоге сработало: почему LLM деградирует на плохой архитектуре точно так же, как команда людей; почему SOLID, DDD и чистая архитектура не устарели, а стали важнее; и как превратить архитектурные договорённости из «пожеланий в CLAUDE.md» в контракт, который машина не может нарушить. С конкретикой: два конфига deptrac для Symfony-бэкенда и пайплайн разработки с субагентом-ревьювером.

Читать далее

Контракт из кода, клиент из контракта: избавляемся от тройного дублирования в API

Уровень сложностиСредний
Время на прочтение4 мин
Охват и читатели10K

Обычно процесс разработки API выглядит так: мы пишем контроллер. Затем каким-то образом его документируем. После чего фронтер, опираясь на такую документацию, пишет клиент.

Мы делаем одну и ту же работу трижды.

В прошлой статье я рассказывал, как избавиться от первого дублирования. С помощью бандла sunrise-studio/symfony-openapi можно генерировать OpenAPI-документ из кода, минуя процесс документирования.

Но это решает проблему только наполовину. Если OpenAPI-документ вытекает из кода, то клиент должен вытекать из OpenAPI-документа. Иначе написание клиента – и есть то самое дублирование.

В этой статье я расскажу как замкнуть цепочку:
Controller → OpenAPI → Client → Feature
Где каждый последующий шаг вытекает из предыдущего, а не дублирует его. 

Читать далее

gRPC в мире PHP: пошаговый гайд по сборке микросервиса на Symfony 8 и RoadRunner

Время на прочтение9 мин
Охват и читатели7.2K

Переход к микросервисной архитектуре неизбежно поднимает вопрос эффективности межсервисного взаимодействия. В PHP традиционный стек на базе PHP-FPM и REST API создает дополнительные накладные расходы: каждый запрос обрабатывается в отдельном процессе, что требует повторной инициализации контейнера зависимостей, загрузки конфигурации и всего контекста приложения. В результате увеличивается latency и снижается пропускная способность сервиса.

В этой статье мы шаг за шагом разработаем высокопроизводительный микросервис на Symfony 7, используя RoadRunner в качестве постоянного приложения-сервера, gRPC для межсервисного взаимодействия и Protocol Buffers для сериализации данных. По итогам вы получите полностью рабочий сервис и поймете, как построить производительную альтернативу классическому стеку PHP-FPM + REST.

Читать далее

OpenAPI без #[OA\...]: как я сделал генератор документации для Symfony

Уровень сложностиСредний
Время на прочтение16 мин
Охват и читатели7.5K

В прошлой статье я уже рассказывал, как однажды устроился на работу и получил пачку «интересных» задач: вручную синхронизировать OpenAPI, оформленный в комментариях к коду, с самим кодом в десятке сервисов.

Тогда это звучало как начало анекдота, но мне было не до смеха.

С тех пор я сменил работу. И, как будто вселенная решила проверить моё чувство юмора, я снова вижу API, где контракт живёт рядом с кодом в ручных #[OA\...] атрибутах.

И это важный момент. Это не история про одну конкретную компанию, один неудачный проект или один старый сервис, который все боятся трогать. Я вижу этот подход в разных местах.

Читать далее

Ближайшие события

Создание сервера для онлайн ММО игр на PHP ч. 17 — внедряю ИИ: механики из одного описания

Уровень сложностиПростой
Время на прочтение11 мин
Охват и читатели15K

Несколько лет я в одиночку пишу сервер для своей 2D MMO RPG. Эта часть — про то, как изменился сам процесс разработки: игровую фичу я по-прежнему придумываю сам, а реализую её уже не один.

Это не демо в духе «модель выдала сниппет». Внутри — настоящая 2D MMO RPG: авторитарный сервер реального времени, тайловые карты, клиент на Unity. ИИ не создал эту систему, а ускорил: то, что раньше занимало дни и недели, теперь укладывается в часы и дни, и в одиночку я держу темп целой команды. Расскажу по порядку, как я к этому пришёл и где у подхода честная граница.

Читать далее

Когда Excel — это часть архитектуры, или история одной не совсем обычной интеграции

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели7.7K

Есть одна мебельная фабрика. Исторически у этой фабрики IT хозяйство было не очень развито и со временем накопилось множество внутренних сервисов для расчета материалов, нагрузки на станки, учета временных затрат работников, доставки и прочего. Исходя из этих расчетов составляется себестоимость продукции. Далее накладывается маржа, и идет расчет доставки и сборки, в зависимости от условий. Фабрика захотела объединить все сервисы в один, основанный на веб, чтобы все расчёты и результаты можно было видеть в одном месте. Было выбрано делать новую веб систему на фреймворке Symfony (PHP).

Читать далее

Symfony Serializer

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели13K

В Symfony есть встроенный компонент Serializer, который покрывает 90% задач. Но его часто обходят стороной, то ли по привычке, то ли из-за того, что документация показывает только тривиальные примеры. А между тем, Serializer — гибкий и вполне годный инструмент, если понимать его архитектуру.

Разберём, как он устроен.

Читать далее

DI‑контейнер Symfony: autowiring, теги и compiler passes

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели8.2K

DI-контейнер — сердечко Symfony. Контроллеры, сервисы, слушатели событий, консольные команды, Voter, нормалайзеры — всё это сервисы, которые живут в контейнере и получают зависимости через него.

Разберём три уровня глубины: autowiring для повседневной работы, теги для расширяемых архитектур, compiler passes для магии уровня фреймворка.

Читать далее

Voters в Symfony

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели8.4K

Привет, Хабр!

В каждом проекте рано или поздно появляется логика вида «этот пользователь может редактировать этот пост, а тот нет». И начинается: if ($post->getAuthor() === $currentUser) в контроллерах, в сервисах, в шаблонах. Копипаста расползается, а потом приходит новое требование — «модератор тоже может редактировать, но только в своей категории» — и вы бегаете по двадцати файлам, молясь, что ничего не забыли.

Symfony Voters — механизм, который выносит всю логику авторизации в одно место. Не аутентификации (тип кто ты?), а именно авторизации (что тебе можно?). Разберём, как это работает.

Разобраться в Voter

ApiKit — чистый REST API в Symfony без шаблонного кода

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели6.9K

REST API на Symfony писать удобно, но есть одна скучная особенность: контроллеры быстро начинают обрастать повторяющимся кодом. Парсинг запроса, валидация, однотипная JSON‑обёртка, try/catch с преобразованием исключений в HTTP‑ответы. Всё это несложно, но со временем размазывается по десяткам эндпоинтов и отвлекает от основной задачи.

Ниже - способ привести все в порядок с помощью небольшого бандла, который я использую в своих проектах.

Читать далее

Symfony Init — быстрый старт проекта без лишней рутины

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели8.2K

Каждый раз, когда хотелось быстро попробовать что‑то на Symfony, начиналась одна и та же история: поднять контейнер с PHP‑FPM или FrankenPHP, провалиться в контейнер, поставить symfony/skeleton, настроить Nginx или Caddyfile, прописать переменные окружения... И всё это до того, как написана хоть одна строчка кода.

DI‑контейнер, консольные команды, компонентная архитектура... Ни для кого не секрет, Symfony заметно ориентируется на Java‑экосистему. Почему бы не попробовать сделать что‑то подобии start.spring.io подумал я.

Так появился пет-проект symfony-init.dev

Читать далее
1
23 ...