PHP-BE1
310 subscribers
337 photos
11 videos
19 files
618 links
Канал по PHP, полезный и интересный контент для всех уровней.
По вопросам сотрудничества @cyberJohnny
Download Telegram
Сегодня расскажу, как правильно и безопасно работать с вводом пользователя в PHP — эта тема давно известна, но всё ещё часто становится причиной уязвимостей.

Часто встречаю в коде такой пример:

$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $id";

Если вы всё ещё так делаете — пора перестать. Это прямой путь к SQL-инъекциям. Даже если вы думаете, что применение intval() решает проблему, это не так.

Правильный метод — использовать подготовленные выражения (prepared statements). Пример с PDO:

$id = $_GET['id'];
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $id]);
$user = $stmt->fetch();

Если вы работаете с mysqli, там тоже есть метод prepare() — не игнорируйте его. Никогда не вставляйте переменные напрямую в SQL-запросы.

Также важно помнить: фильтрация — это не экранирование, а экранирование — не защита. Настоящая защита — это отделение данных от SQL-кода с помощью prepare().

А как вы проверяете и обрабатываете данные от пользователей? Используете ли свои обёртки или ORM? Поделитесь опытом в комментариях.

👉 [|@php_be1]
Открытый вебинар «Локализация текстов в Symfony» в OTUS

🗓 15 мая, 20:00 МСК · онлайн · бесплатно
👤 Спикер — Михаил Каморин, Tech Lead Avito, 5 лет на Symfony

Symfony уверенно решает задачу мультиязычности — но что, если переводы живут в БД, а не в yaml-файлах? На вебинаре разберём базовый пример, как «подружить» symfony/translation с динамическими строками — без глубокого погружения во все тонкости компонента.

Что разберём
• Стандартная локализация статических текстов: настройка, plural-формы, fallback-языки.
• Подход к динамическим переводам в БД: таблицы, базовый Doctrine-маппинг.
• Практический пример: сохраним и извлечём строки, посмотрим метрики в Profiler.

Кому полезно
— Middle/Senior PHP-разработчикам, архитекторам и тимлидам, которые строят мульти-язычные сервисы или ищут нетривиальные модели хранения.

Формат — 60 минут концентрированной практики + Q&A без воды.

🔗 Регистрация

Слоты ограничены; участие бесплатное.

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Релиз PHP 8.4.7 и 8.3.21
https://www.php.net/ChangeLog-8.php

@php_be1
Сегодня я хочу рассказать о приёме, который значительно облегчает мне жизнь при отладке в PHP.

🛠 Как удобно отлаживать сложные объекты в Laravel?

Когда работаешь с коллекциями, запросами или вложенными структурами, функции dd() или dump() часто создают слишком много лишней информации. Но есть более элегантный способ:
logger($someObject);

Этот метод не останавливает выполнение скрипта, в отличие от dd(), и записывает данные в файл storage/logs/laravel.log. И вот здесь начинается самое интересное:

📌 Хочешь, чтобы лог был понятным? Добавь пользовательский формат:
logger()->info('User data', [$user->toArray()]);
Или ещё лучше — используй вспомогательные функции Laravel, например tap():
tap($response, fn($res) => logger($res->toArray()));

💡 Это особенно полезно, когда нужно просто посмотреть данные, не прерывая работу приложения.

🔥 Плюс: в файле .env можно установить LOG_LEVEL=debug, и тогда ты увидишь всё, даже внутренние процессы Laravel.

Такие мелочи делают обычную отладку более организованной и удобной.

А как ты обычно отлаживаешь Laravel — через dd() или используешь свои методы?

👉 [|@php_be1]
Через 2 дня — бесплатный вебинар OTUS «Локализация текстов в Symfony»

🗓 15 мая, 20:00 МСК · онлайн
👤 Спикер — Михаил Каморин, Tech Lead Avito

Symfony-проекты часто сталкиваются с задачей мультиязычности. Как локализовать статические строки — понятно, а что делать с динамическими текстами в БД? На вебинаре покажем базовый рабочий маппинг для обоих сценариев.

Что успеем за 60 минут
• Настроим компонент symfony/translation для статических файлов.
• Построим простую схему БД и Doctrine-маппинг для динамических переводов.
• Сохраним, извлечём и отладим строки в Profiler.
• Ответим на живые вопросы в Q&A.

Кому стоит прийти
— Middle/Senior PHP-разработчикам, архитекторам и тимлидам, которым нужны готовые паттерны локализации или нестандартные модели хранения.

⚡️ Слотов осталось мало — регистрация закроется в день мероприятия

🔗 Успейте записаться

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Сегодня я покажу вам, как элегантно избавиться от жёсткой зависимости от фреймворков в ваших PHP-проектах. Особенно это актуально, если вы работаете с Laravel, Symfony или любым другим тяжеловесом, и со временем начинаете чувствовать, что проект стал слишком «завязан» на конкретную экосистему.

💡 Проблема: вы используете, скажем, Illuminate\Http\Request, Illuminate\Support\Collection, или ContainerInterface из Laravel — и всё, вы уже внутри. Попробуйте вынести бизнес-логику в отдельный пакет — и он сразу неработоспособен вне Laravel.

🎯 Решение: разделяйте инфраструктуру и домен.
Вот несколько практических шагов:

1. Вводите интерфейсы в домене.
Вместо Illuminate\Http\Request — свой App\Contracts\RequestInterface. Это можно реализовать через адаптер или DTO.

2. Убирайте фреймворк из бизнес-логики.
Доменный код не должен знать про контроллеры, контейнеры и фасады. Он должен работать с чистыми данными, переданными через интерфейсы или value-объекты.

3. Интеграция на уровне Application Layer.
Фреймворк используется для "склейки" — он передаёт данные в домен и получает результат. Например, Laravel Controller вызывает сервис, но сервис не зависит от Laravel.

4. Проверяйте независимость.
Попробуйте запустить доменную часть проекта в консольном скрипте или тесте вне Laravel — если всё работает, вы на правильном пути.

📦 В результате вы получаете код, который легко тестировать, переносить между проектами, использовать вне фреймворка — хоть в Laravel, хоть в Symfony, хоть в чистом PHP.

Я лично начал писать всю бизнес-логику как Composer-пакеты без зависимости от Laravel. Это не просто — особенно поначалу — но это окупается на 100%.

Как вы решаете проблему зависимости от фреймворков? Поделитесь опытом 👇

👉 [|@php_be1]
А вы знали, что можно задать дефолтные значения полей БД не только в миграциях, но и в Eloquent-модели с помощью $attributes?

@php_be1
Сегодня расскажу про одну из самых частых болей в любом проекте на Laravel — отладку запросов с Eloquent и N+1 проблемой.

Ты наверняка сталкивался с ситуацией: всё работает, но чуть-чуть замедляется. Начинаешь копать и видишь кучу повторяющихся SQL-запросов. Это классическая N+1 проблема — когда вместо одного запроса Laravel делает десятки.

👀 Как это проявляется?

У тебя есть, например, список постов и у каждого поста автор:
$posts = Post::all();

foreach ($posts as $post) {
echo $post->user->name;
}

Laravel выполнит 1 запрос на посты и N запросов на пользователей. А должен был бы — 2 запроса максимум.

🛠 Решение простое — eager loading:
$posts = Post::with('user')->get();

Теперь Laravel сначала загрузит всех постов, а потом сразу всех юзеров одним вторым запросом.

📦 Но как быстро выявить такие ошибки?

Используй Laravel Debugbar или Clockwork. Они наглядно показывают все SQL-запросы и сразу виден N+1.

Ещё один вариант — в проде подключить Laravel Telescope, если это безопасно, или поставить простую логику, которая логирует количество SQL-запросов на каждый HTTP-запрос.

Совет: всегда используй with() при выборке данных для списков, особенно если в шаблоне дергаешь связанные модели.

👉 [|@php_be1]
Глобализируйте ограничения параметров маршрутов

@php_be1
Новый оператор конвейера в PHP 8.5
https://www.amitmerchant.com/the-pipe-operator-php-85/

@php_be1
Обработка ошибок транзакций в Laravel 12.9
https://www.harrisrafto.eu/elegant-transaction-error-handling-in-laravel/

@php_be1
Сегодня я расскажу вам о том, как настроить эффективное логирование ошибок в PHP-приложениях с помощью библиотеки Monolog.

В повседневной разработке критично не упустить важные ошибки и события, но при этом не завалить логи мусором. Monolog позволяет:

1. Группировать логи по каналам
Вы можете создавать каналы для разных частей приложения:
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$dbLogger = new Logger('database');
$dbLogger->pushHandler(new StreamHandler(__DIR__.'/logs/db.log', Logger::WARNING));

2. Использовать разные обработчики (handlers)
Отправка ошибок в файлы, на почту или в Slack:
use Monolog\Handler\NativeMailerHandler;
$emailHandler = new NativeMailerHandler('you@domain.com', 'DB Error', 'app@domain.com', Logger::ERROR);
$dbLogger->pushHandler($emailHandler);

3. Добавлять процессоры (processors)
Автоматически дополнять каждый лог юзер-агентом, IP и временем выполнения:
use Monolog\Processor\WebProcessor;
$dbLogger->pushProcessor(new WebProcessor());

4. Форматировать вывод
Пример простого форматера:
use Monolog\Formatter\LineFormatter;
$formatter = new LineFormatter("[%datetime%] %channel%.%level_name%: %message% %context%\n");
$handler->setFormatter($formatter);

🎯 Совет на практике: заведите отдельные файлы логов под разные уровни важности (INFO, WARNING, ERROR), чтобы при поиске нужных записей достаточно было открыть один файл.

А как вы организуете логи в своих проектах? Делитесь опытом в комментариях!

👉 [|@php_be1]
Новый метод toResource() в Laravel 12 упрощает код

@php_be1
Сегодня расскажу вам про одну простую, но очень полезную привычку для любого PHP-разработчика — вести чек-листы по задачам прямо в коде.

Когда проект становится чуть больше "визитки", начинают скапливаться мелкие задачи: что-то подправить, где-то доделать, что-то не забыть протестировать. В итоге куча мыслей крутится в голове, а шанс что-то упустить растёт. Как я с этим борюсь?

Я просто добавляю короткие TODO-комментарии в нужных местах кода. Например:
// TODO: Проверить валидацию email после изменений
// TODO: Перевести этот блок на отдельный сервис
Каждый раз перед коммитом быстро пробегаюсь по проекту поиском по "TODO" — и вижу все свои маленькие хвосты. А когда задач становится много, использую расширения для IDE (например, "TODO Highlight" в VSCode) — и визуально сразу видно все невыполненные задачи.

Почему это работает:

* Не надо держать всё в голове.
* Любой разработчик быстро вникает в текущие проблемы кода.
* Легче планировать рефакторинг.
* Сложно забыть про важную доработку.

Советую прямо сегодня попробовать добавить пару своих TODO в код. Дай знать, пользуешься ли ты таким приёмом или предпочитаешь другие методы? Пиши в комментариях!

👉 [|@php_be1]