Библиотека пхпшника | PHP, Laravel, Symfony, CodeIgniter
11K subscribers
1.57K photos
26 videos
26 files
4.31K links
Все самое полезное для пхпшника в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/bca892d6

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a5d13cd6fa92100ee6f68b
Download Telegram
⚖️ whereHas() vs whereRelation() в Laravel

короче — не значит понятнее

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

Часто советуют заменить whereHas() на whereRelation():
// было
User::whereHas('profile', function ($q) {
$q->where('is_verified', false);
})->get();

// стало
User::whereRelation('profile', 'is_verified', false)->get();


Формально — да, код короче.
Практически — не всё так радужно.

🧠 В чём реальная разница
whereHas() — явно про отношения
User::query()
->whereHas('profile', fn ($q) => $q->where('is_verified', false))
->get();


С первого взгляда понятно:

🔸фильтрация по relation

🔸логика живёт внутри профиля

🔸условия легко расширяются

🔸запрос честно отражает намерение

whereRelation() — скрывает сложность
User::whereRelation('profile', 'is_verified', false)->get();


Читается как фильтр по колонке users.
Но на деле — это подзапрос к связанной таблице.

❗️ Это вводит в заблуждение, особенно при чтении чужого кода.

🧩 Масштабирование условий

С whereHas() — естественно и прозрачно:
->whereHas('profile', fn ($q) => $q
->where('is_verified', false)
->whereNotNull('phone')
->where('age', '>', 18)
)


С whereRelation():

🔸либо цепочка вызовов

🔸либо возврат к whereHas()

🔸либо каша из стилей

🔍 Поиск и поддержка кода

Реальный кейс:

«Эндпоинт тормозит, ищем фильтрацию по отношениям»

whereHas() — легко найти поиском

whereRelation() — прячется среди обычных where

Для поддержки и отладки это критично.

⚙️ Производительность — миф

whereRelation() не быстрее.
Под капотом — тот же whereHas() и почти идентичный SQL.

Если медленно:

🔸нет индексов

🔸не тот подход к запросу

Метод тут ни при чём.

🧱 Проблема консистентности

Что происходит в проектах:

1. Сначала whereRelation() — «быстро и красиво»

2. Потом требования растут

3. Появляется whereHas()

4. В коде — два стиля без причины

5. В ревью — споры

Если сразу использовать whereHas():

🔸один паттерн

🔸единый стиль

🔸код готов к росту

🧠 Внутренности Laravel

Без магии:
whereRelation() — это обёртка над whereHas().
Не умнее. Не быстрее. Просто без closure.

📌 Правило на практике


Можно whereRelation(), если:

🔸один простой фильтр

🔸скрипт, отчёт, админка

🔸логика точно не вырастет

Лучше whereHas(), если:

🔸бизнес-логика

🔸командная разработка

🔸код придётся читать и менять

Экономия пары символов — плохой аргумент.
Пишите код для того, кто откроет файл через полгода.
В реальных проектах честный whereHas() почти всегда выигрывает.

👉 Ссылка на статью

Библиотека пхпшника

#элементарный_выбор
4👍1🥱1
🔍 Can I PHP: проверяем доступность фичи налету

Расширение позволяет проверить доступность определенной функции/метода в различных версиях PHP и получить краткое описание возможностей.

👉 Сайт

#инструменты
2
How to: правильно обрабатывать ошибки валидации в Symfony

DTO + #[MapRequestPayload] в Symfony выглядят отлично.
Но ошибки валидации по умолчанию — шумные, разные по формату и неудобные для фронта.
Из-за этого часто появляются:
🔸 try/catch в контроллерах
🔸 дублирующийся маппинг ошибок
🔸 хаос в API-ответах

Правильный подход
Пусть валидация падает сама, а форматирование ошибок происходит глобально, один раз.
Это решает Symfony Validation Response Bundle:
🔹 перехватывает ошибки из #[MapRequestPayload], #[MapQueryString], #[MapUploadedFile];
🔹 возвращает чистый JSON;
🔹 единый формат для всех эндпоинтов;
🔹 без логики в контроллерах.

🚀 Быстрый старт

composer require soleinjast/symfony-validation-response

Без конфигурации. Есть simple, RFC7807 и кастомные форматтеры.

👉 Подробный разбор и примеры — в статье.

Библиотека пхпшника
⌨️ Топ-вакансий по PHP за неделю

PHP разработчик — от 170 000 до 240 000 ₽, Удалёнка (Москва)

Middle+ / Senior Laravel разработчик — от 2200 до 3000 $, Удаленка (Москва)

Веб-программист PHP — 200 000 до 300 000 ₽, Удаленка (Москва)

➡️ Еще больше топовых вакансий — в нашем канале PHP Jobs
Roadmap: Внедрение ИИ-агентов в PHP-приложения

ИИ-агенты — это новый стандарт автоматизации бэкенда. Разработчикам на PHP пора осваивать архитектуру автономных систем для расширения возможностей своих проектов.

Этапы обучения:

— изучение принципов взаимодействия с языковыми моделями через API;

— проектирование агентской логики: инструменты, память, планирование;

— интеграция мультиагентных систем в веб-сервисы;

— оптимизация работы агентов для решения бизнес-задач.

Курс «Разработка ИИ-агентов» проведёт вас от теории до реализации готовых ИИ-решений.

Стать AI-разработчиком

До 19 января действует акция «3 в 1»: купите один курс — два получите бесплатно.
😁1
Yii3. Официальный релиз

Это случилось! Yii3 официально выпущен после многих лет интенсивной разработки и полировки.

🔗 Хабр

Библиотека пхпшника
🎉29😁11
🧠 Отключайте логирование SQL при тяжёлых запросах

🧠 Суть проблемы
Когда вы выполняете много SQL-запросов, особенно в пакетных операциях (импорт больших объёмов данных, миграции, мигрейт-скрипты), ORM может логировать каждый запрос.
Такое логирование полезно при отладке, но в рабочих сценариях оно:
генерирует огромное количество записей в памяти,
может привести к утечкам памяти (memory leak) при Doctrine, если логгер накапливает записи,
увеличивает время выполнения операции, так как обработка логов сама по себе не бесплатна.

Почему отключать логирование полезно
🔹 При больших импортных задачах или миграциях сотни тысяч запросов могут накапливаться в логере — это вызывает рост потребления памяти и может привести к «зависанию» процесса.
🔹 Если логирование не нужно в этом контексте, его отключение убирает ненужную нагрузку и ускоряет выполнение операций.
🔹 Это особенно важно на production-задачах, где производительность имеет приоритет над подробным аудитом запросов.

🛠️ Как отключить логирование в разных экосистемах

🟦 Laravel (Eloquent / Query Logging)
Laravel логирует запросы, если включён режим отладки или уровень логов очень подробный.
Чтобы уменьшить SQL-логирование, в .env:

APP_DEBUG=false
LOG_LEVEL=info

Это снизит объём логов, не выводя SQL-запросы по умолчанию (они обычно логируются на уровне debug).
Если же вы используете кастомный логгер запросов — отключите его в продакшене.

🟩 Symfony / Doctrine ORM
Doctrine по умолчанию может логировать SQL через SQLLogger (особенно в dev-режиме).
Для отключения логгера Doctrine:

$emConfig = $entityManager->getConnection()->getConfiguration();
$emConfig->setSQLLogger(null);

Это полностью выключит SQL-логирование для этого соединения.
Такой подход особенно полезен при массовых операциях, например в консольных командах или миграциях.

💡 Значение null удаляет логгер, и Doctrine перестаёт накапливать записи о каждом выполненном SQL.

⚠️ В более новой версии Doctrine SQLLogger был заменён системой middlewares, и для полного отключения придётся убирать middleware-логгеры — см. документацию.

📌 Пример использования в консоли (Symfony)
Если у вас есть импорты/массовая обработка в консольной команде — отключите логгер в начале:


public function execute(InputInterface $input, OutputInterface $output): int
{
$config = $this->entityManager->getConnection()->getConfiguration();
$config->setSQLLogger(null);

// дальнейшая обработка
}


Такой трюк помогает избежать накопления большого количества логов в памяти и снижает риски OOM (Out Of Memory).

🧠 Когда это стоит делать
Тяжёлые операции с данными: импорт/экспорт больших таблиц, миграции
Длительные фоновые задачи в очередях/консоли
Прод-окружение, где логи не нужны для каждого SQL-запроса

⚠️ Когда не стоит отключать
Если вы на этапе отладки и хотите видеть каждый запрос для оптимизации
Если нужно собирать подробную аналитику SQL-вызовов
Если у вас разработка и подробные логи помогают тестировать логику

Библиотека пхпшника
👍2
Небольшой совет по PHP, который сэкономит время (и строки кода)

Недавно при ревью PHP-проекта всё работало идеально: тесты зелёные, багов нет.
Но в глаза бросилось другое — один и тот же шаблон в каждом конструкторе(фото 1)

Технически всё корректно.
Практически — это рутина.

Когда в проекте:
— десятки классов
— по 5–10 свойств в каждом
вы постоянно пишете один и тот же бойлерплейт. Это шум, а не логика.

Что изменилось с PHP 8.0

В PHP 8.0 появился Constructor Property Promotion.
Он позволяет объявлять и инициализировать свойства прямо в конструкторе(фото 2)

Результат:
— нет отдельных свойств
— нет $this->name = $name
— поведение то же
— кода меньше
— читать быстрее

Мозг фокусируется на зависимостях класса, а не на механике.
Видимость — любая
class Post
{
public function __construct(
public string $title,
public string $content,
private int $authorId
) {}
}


Работает ровно так, как ожидается.

Реальный эффект на проекте

В одном Laravel-сервисе было 12 свойств.
Конструктор — ~30 строк.
После рефакторинга:
— 6 строк
— логика не изменилась
— код стало проще ревьюить

Времени: ~2 минуты (multi-cursor в VS Code).

Когда стоит использовать
Используйте promotion, если:
— свойства задаются только в конструкторе
— нет дополнительной логики при присваивании
— хотите чистый, современный PHP

Когда не стоит
Не используйте, если:
— нужна валидация
— вы трансформируете значение
— важно явно показать логику инициализации

Здесь старый способ — осознанно лучше.

🔗Ссылка на статью

Библиотека пхпшника
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
6🥱4
This media is not supported in your browser
VIEW IN TELEGRAM
🧑‍💻 Пишете на PHP, но всё чаще появляются задачи, где стандартного стека не хватает? Интенсивные вычисления, интеграции с нативным кодом, необходимость выжать максимум из железа — здесь в игру входят FFI и WASM.

📖 На открытом уроке поговорим о сценариях применения, типичных задачах, для которых подключают FFI или WebAssembly, и разберём реальные примеры.

❗️ Вы увидите, какие преимущества дают FFI и WASM с точки зрения производительности и гибкости и архитектуры, а также с какими рисками и ограничениями придётся считаться. Это полезно тем, кто хочет выходить за рамки классического PHP и понимать, какие инструменты есть над фреймворками.

▶️ Встречаемся 26 января в 20:00 МСК в преддверие старта курса «PHP Developer. Professional». Регистрация открыта: https://clc.to/u0ASNg

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM