Сегодня я расскажу, как удобно осуществлять логирование в Laravel, не загромождая код и не превращая проект в хаос из Log::info() на каждом шагу.
💡 Правильное использование каналов логирования
Laravel предлагает мощную систему логирования на основе Monolog. Однако часто мы ограничиваемся стандартным логом, что не совсем разумно.
Например, можно создать отдельный канал для логов по оплате:
// config/logging.php
'channels' => [
'payment' => [
'driver' => 'single',
'path' => storage_path('logs/payment.log'),
'level' => 'info',
],
],
Теперь в нужном месте можно записывать:
Log::channel('payment')->info('Платёж прошёл', ['user_id' => $user->id, 'amount' => $amount]);
И всё — никакой путаницы. В laravel.log остаётся только то, что важно для всего проекта, а логи по оплате хранятся отдельно. Их можно также отправлять в телеграм, если настроить webhook.
👀 Бонус: helper-функция
Чтобы писать меньше:
if (!function_exists('payment_log')) {
function payment_log($message, array $context = []) {
\Log::channel('payment')->info($message, $context);
}
}
Теперь можно просто вызывать payment_log('Платёж принят') в любом месте.
Напишите в комментариях, какие каналы логирования используете и куда отправляете логи — в файл, телеграм или Sentry?
💡 Правильное использование каналов логирования
Laravel предлагает мощную систему логирования на основе Monolog. Однако часто мы ограничиваемся стандартным логом, что не совсем разумно.
Например, можно создать отдельный канал для логов по оплате:
// config/logging.php
'channels' => [
'payment' => [
'driver' => 'single',
'path' => storage_path('logs/payment.log'),
'level' => 'info',
],
],
Теперь в нужном месте можно записывать:
Log::channel('payment')->info('Платёж прошёл', ['user_id' => $user->id, 'amount' => $amount]);
И всё — никакой путаницы. В laravel.log остаётся только то, что важно для всего проекта, а логи по оплате хранятся отдельно. Их можно также отправлять в телеграм, если настроить webhook.
👀 Бонус: helper-функция
Чтобы писать меньше:
if (!function_exists('payment_log')) {
function payment_log($message, array $context = []) {
\Log::channel('payment')->info($message, $context);
}
}
Теперь можно просто вызывать payment_log('Платёж принят') в любом месте.
Напишите в комментариях, какие каналы логирования используете и куда отправляете логи — в файл, телеграм или Sentry?
⚡️Уже умеете работать с PHP и хотите перейти на новый уровень? Laravel даст вам системный подход, архитектуру без хаоса и скорость, которая радует менеджеров и ревьюеров.
Обучение от OTUS — это живая работа с кодом, практикующие эксперты и фокус на бизнес-задачи, а не абстрактные “учебные примеры”. Мы не перегружаем теорией — только то, что действительно нужно в реальных проектах. Через 3 месяца вы будете уверенно использовать Laravel в проде и уметь разворачивать защищённые, протестированные приложения.
Программа обновлена под текущие требования рынка, а диплом OTUS котируется у ведущих компаний.
👉Пройдите вступительное тестирование и получите скидку на обучение: https://clck.ru/3LZZHk
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Обучение от OTUS — это живая работа с кодом, практикующие эксперты и фокус на бизнес-задачи, а не абстрактные “учебные примеры”. Мы не перегружаем теорией — только то, что действительно нужно в реальных проектах. Через 3 месяца вы будете уверенно использовать Laravel в проде и уметь разворачивать защищённые, протестированные приложения.
Программа обновлена под текущие требования рынка, а диплом OTUS котируется у ведущих компаний.
👉Пройдите вступительное тестирование и получите скидку на обучение: https://clck.ru/3LZZHk
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Сегодня я поделюсь с вами простым способом, как решить сложную проблему с session_start() в PHP.
Недавно один из подписчиков столкнулся с ошибкой "Cannot send session cache limiter - headers already sent". Думаю, многие PHP-разработчики хотя бы раз в жизни это видели.
Давайте разберемся.
💥 Причина
Ошибка возникает, когда session_start() вызывается после того, как браузеру уже были отправлены заголовки. В PHP это значит, что перед session_start() был echo, пробел вне тегов <?php ?> или даже var_dump() для отладки. Любой вывод в браузер означает, что PHP уже отправил заголовки. А session_start() пытается их изменить — и мы получаем ошибку.
✅ Как лечить
1. Ищем вывод перед session_start()
- Проверь, нет ли echo, print, отладочных функций или лишних символов перед вызовом session_start().
- Включи буферизацию ob_start() в начале скрипта — это поможет временно «подавить» вывод:
ob_start();
session_start();
Но это временное решение. Лучше всё-таки убрать лишний вывод.
2. Идеальная структура файла
<?php
// Никакого вывода до этого момента!
session_start();
// Остальной код
?>
3. Ищи BOM
Иногда редакторы, такие как Notepad++, добавляют невидимый символ BOM в начало файла. Он тоже считается выводом. Это решается сохранением файла в UTF-8 без BOM.
🛠 Мой способ отладки
Когда всё выглядит правильно, но ошибка всё равно возникает:
- Создай новый чистый файл и вставь туда session_start() — если всё работает, значит проблема в другом коде.
- Используй headers_sent():
if (headers_sent($file, $line)) {
echo "Вывод уже начат в $file на строке $line";
}
Это сэкономило мне много времени при отладке старых легаси-проектов.
👉 [|@php_be1]
Недавно один из подписчиков столкнулся с ошибкой "Cannot send session cache limiter - headers already sent". Думаю, многие PHP-разработчики хотя бы раз в жизни это видели.
Давайте разберемся.
💥 Причина
Ошибка возникает, когда session_start() вызывается после того, как браузеру уже были отправлены заголовки. В PHP это значит, что перед session_start() был echo, пробел вне тегов <?php ?> или даже var_dump() для отладки. Любой вывод в браузер означает, что PHP уже отправил заголовки. А session_start() пытается их изменить — и мы получаем ошибку.
✅ Как лечить
1. Ищем вывод перед session_start()
- Проверь, нет ли echo, print, отладочных функций или лишних символов перед вызовом session_start().
- Включи буферизацию ob_start() в начале скрипта — это поможет временно «подавить» вывод:
ob_start();
session_start();
Но это временное решение. Лучше всё-таки убрать лишний вывод.
2. Идеальная структура файла
<?php
// Никакого вывода до этого момента!
session_start();
// Остальной код
?>
3. Ищи BOM
Иногда редакторы, такие как Notepad++, добавляют невидимый символ BOM в начало файла. Он тоже считается выводом. Это решается сохранением файла в UTF-8 без BOM.
🛠 Мой способ отладки
Когда всё выглядит правильно, но ошибка всё равно возникает:
- Создай новый чистый файл и вставь туда session_start() — если всё работает, значит проблема в другом коде.
- Используй headers_sent():
if (headers_sent($file, $line)) {
echo "Вывод уже начат в $file на строке $line";
}
Это сэкономило мне много времени при отладке старых легаси-проектов.
👉 [|@php_be1]
Как защитить вебхуки в Laravel от подделки данных
@php_be1
https://christalks.dev/post/secure-your-webhooks-in-laravel-preventing-data-spoofing-fe25a70e
@php_be1
https://christalks.dev/post/secure-your-webhooks-in-laravel-preventing-data-spoofing-fe25a70e
christalks.dev
Secure Your Webhooks in Laravel: Preventing Data Spoofing
Learn how to implement robust authentication using pre-shared keys and HMAC signatures to protect your webhook endpoints.
Новый фреймворк Tempest
Фреймворк, который не мешает писать код
https://tempestphp.com/blog/discovery-explained
@php_be1
Фреймворк, который не мешает писать код
https://tempestphp.com/blog/discovery-explained
@php_be1
Через 2 дня — бесплатный вебинар OTUS «Почему стоит выбрать Symfony для нового проекта»
🗓 29 апреля, 20:00 МСК · онлайн
👤 Спикер — Михаил Каморин, Tech Lead Avito
Symfony остаётся ядром экосистемы PHP. Разберём, почему фреймворк подходит для запуска и долгосрочной поддержки продуктов.
Что обсудим
• Модульность: более 25 компонентов подключаются по нужде.
• Гибкость: мощный DI‑контейнер и переопределяемые сервисы.
• Стабильность: LTS 3 года, минорные версии совместимы назад.
• Dev‑ускорители: Symfony CLI, Flex, автоконфигурация, Profiler.
Кому полезно
— PHP‑разработчикам, которые выбирают стек для нового проекта.
— Тем, кому нужны строгие аргументы «за» Symfony или PHP.
⚡️ Слотов осталось мало — регистрация закроется в день мероприятия.
🔗 Успейте записаться → https://clck.ru/3LdKmm
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🗓 29 апреля, 20:00 МСК · онлайн
👤 Спикер — Михаил Каморин, Tech Lead Avito
Symfony остаётся ядром экосистемы PHP. Разберём, почему фреймворк подходит для запуска и долгосрочной поддержки продуктов.
Что обсудим
• Модульность: более 25 компонентов подключаются по нужде.
• Гибкость: мощный DI‑контейнер и переопределяемые сервисы.
• Стабильность: LTS 3 года, минорные версии совместимы назад.
• Dev‑ускорители: Symfony CLI, Flex, автоконфигурация, Profiler.
Кому полезно
— PHP‑разработчикам, которые выбирают стек для нового проекта.
— Тем, кому нужны строгие аргументы «за» Symfony или PHP.
⚡️ Слотов осталось мало — регистрация закроется в день мероприятия.
🔗 Успейте записаться → https://clck.ru/3LdKmm
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Сегодня я хочу рассказать вам о простом, но очень полезном приёме для работы с массивами в PHP — использовании функции array_column().
Существует частая задача: из многомерного массива "извлечь" только один столбец данных. Например, у вас есть массив пользователей:
$users = [
['id' => 1, 'name' => 'Иван', 'email' => 'ivan@example.com'],
['id' => 2, 'name' => 'Ольга', 'email' => 'olga@example.com'],
['id' => 3, 'name' => 'Павел', 'email' => 'pavel@example.com'],
];
И нужно получить только список всех email'ов. Многие решают это с помощью foreach, но есть более элегантное решение:
$emails = array_column($users, 'email');
Результат будет таким:
[
'ivan@example.com',
'olga@example.com',
'pavel@example.com'
]
Кроме того, array_column() позволяет указать третий параметр — ключ массива. Например, можно сделать email по id:
$emailsById = array_column($users, 'email', 'id');
И тогда получится:
[
1 => 'ivan@example.com',
2 => 'olga@example.com',
3 => 'pavel@example.com'
]
Это удобный способ быстрого преобразования данных без лишнего кода.
Используете ли вы array_column() в своих проектах? Или предпочитаете что-то другое? Напишите в комментариях!
👉 [|@php_be1]
Существует частая задача: из многомерного массива "извлечь" только один столбец данных. Например, у вас есть массив пользователей:
$users = [
['id' => 1, 'name' => 'Иван', 'email' => 'ivan@example.com'],
['id' => 2, 'name' => 'Ольга', 'email' => 'olga@example.com'],
['id' => 3, 'name' => 'Павел', 'email' => 'pavel@example.com'],
];
И нужно получить только список всех email'ов. Многие решают это с помощью foreach, но есть более элегантное решение:
$emails = array_column($users, 'email');
Результат будет таким:
[
'ivan@example.com',
'olga@example.com',
'pavel@example.com'
]
Кроме того, array_column() позволяет указать третий параметр — ключ массива. Например, можно сделать email по id:
$emailsById = array_column($users, 'email', 'id');
И тогда получится:
[
1 => 'ivan@example.com',
2 => 'olga@example.com',
3 => 'pavel@example.com'
]
Это удобный способ быстрого преобразования данных без лишнего кода.
Используете ли вы array_column() в своих проектах? Или предпочитаете что-то другое? Напишите в комментариях!
👉 [|@php_be1]
ДевОпс и Laravel: Очереди и Обработчики в Продакшене
https://martinjoo.dev/laravel-queues-and-workers-in-production
@php_be1
https://martinjoo.dev/laravel-queues-and-workers-in-production
@php_be1
Сегодня я хочу поделиться с вами одной распространенной ошибкой, которую часто совершают начинающие PHP-разработчики — это неправильная работа с датами и временем.
Когда вы используете такие функции, как date(), strtotime(), time() напрямую, не установив явным образом временную зону (timezone), ваш код может начать вести себя непредсказуемо. Особенно это касается проектов, которые работают на серверах в разных регионах.
Чтобы избежать проблем:
- Всегда устанавливайте временную зону явно с помощью date_default_timezone_set('Your/Timezone'); в начале вашего приложения.
- Или лучше используйте объекты DateTime и DateTimeZone, так как они значительно удобнее для работы с временными зонами и манипуляциями с датами.
Вот пример правильного подхода:
$date = new DateTime('now', new DateTimeZone('Europe/Moscow'));
echo $date->format('Y-m-d H:i:s');
И еще одна рекомендация — всегда храните даты в базе данных в формате UTC, а при выводе преобразовывайте их в нужную временную зону для пользователя.
Небольшая дисциплина в работе с временем сэкономит вам много нервов в будущем. Это проверено на реальных проектах!
👉 [|@php_be1]
Когда вы используете такие функции, как date(), strtotime(), time() напрямую, не установив явным образом временную зону (timezone), ваш код может начать вести себя непредсказуемо. Особенно это касается проектов, которые работают на серверах в разных регионах.
Чтобы избежать проблем:
- Всегда устанавливайте временную зону явно с помощью date_default_timezone_set('Your/Timezone'); в начале вашего приложения.
- Или лучше используйте объекты DateTime и DateTimeZone, так как они значительно удобнее для работы с временными зонами и манипуляциями с датами.
Вот пример правильного подхода:
$date = new DateTime('now', new DateTimeZone('Europe/Moscow'));
echo $date->format('Y-m-d H:i:s');
И еще одна рекомендация — всегда храните даты в базе данных в формате UTC, а при выводе преобразовывайте их в нужную временную зону для пользователя.
Небольшая дисциплина в работе с временем сэкономит вам много нервов в будущем. Это проверено на реальных проектах!
👉 [|@php_be1]
Наблюдатели и Слушатели в Laravel — в чём разница?
https://bert.gent/articles/2025-04-23/laravel-observers-vs-event-listeners-whats-the-difference
@php_be1
https://bert.gent/articles/2025-04-23/laravel-observers-vs-event-listeners-whats-the-difference
@php_be1
FastExcelWriter — решение проблемы с PhpSpreadsheet
Наверняка каждый php-разработчик, который хоть раз работал с чтением или записью Excel-файлов, знает о библиотеке PhpSpreadsheet (ранее - PHPExcel). Это мощная библиотека на чистом php, позволяющая читать и, что более важно, создавать Excel-таблицы. Всё хорошо, пока вы работаете с небольшими наборами данных. Но при работе с большими файлами PhpSpreadsheet начинает сильно потреблять память, а производительность резко падает, и php-скрипт, использующий эту библиотеку, часто просто зависает из-за превышения времени выполнения. Проблема заключается в архитектуре библиотеки.
Библиотека PhpSpreadsheet, казалось бы, спроектирована довольно грамотно: листы таблицы, строки, ячейки и другие сущности — все это классы, стили, форматы и различные свойства также представляют собой классы. Когда создается таблица, в памяти создается огромное количество взаимосвязанных объектов, им задаются свойства, выполняются различные манипуляции, ячейки заполняются данными, и всё это хранится в памяти, а запись в файл происходит только в момент сохранения.
https://habr.com/ru/articles/904710/
👉 [|@php_be1]
Наверняка каждый php-разработчик, который хоть раз работал с чтением или записью Excel-файлов, знает о библиотеке PhpSpreadsheet (ранее - PHPExcel). Это мощная библиотека на чистом php, позволяющая читать и, что более важно, создавать Excel-таблицы. Всё хорошо, пока вы работаете с небольшими наборами данных. Но при работе с большими файлами PhpSpreadsheet начинает сильно потреблять память, а производительность резко падает, и php-скрипт, использующий эту библиотеку, часто просто зависает из-за превышения времени выполнения. Проблема заключается в архитектуре библиотеки.
Библиотека PhpSpreadsheet, казалось бы, спроектирована довольно грамотно: листы таблицы, строки, ячейки и другие сущности — все это классы, стили, форматы и различные свойства также представляют собой классы. Когда создается таблица, в памяти создается огромное количество взаимосвязанных объектов, им задаются свойства, выполняются различные манипуляции, ячейки заполняются данными, и всё это хранится в памяти, а запись в файл происходит только в момент сохранения.
https://habr.com/ru/articles/904710/
👉 [|@php_be1]
Сегодня я расскажу, как быстро и удобно настроить автозагрузку классов в PHP без применения Composer.
Мы все ценим Composer, но иногда он не подходит — например, для маленьких проектов, скриптов или наследуемого кода, где Composer изначально не использовался. В таких случаях можно сделать простую, но эффективную автозагрузку самостоятельно.
Приведу простой пример:
spl_autoload_register(function ($class) {
$baseDir = __DIR__ . '/src/';
$classPath = str_replace('\\', '/', $class) . '.php';
$file = $baseDir . $classPath;
if (file_exists($file)) {
require $file;
}
});
Что здесь происходит:
- spl_autoload_register регистрирует анонимную функцию, которая срабатывает при попытке использовать неопределённый класс.
- Класс App\Services\MailService преобразуется в путь src/App/Services/MailService.php.
- Если файл найден — он подключается.
Это очень удобный способ организовать код и избавиться от множества require.
Если нужна большая гибкость — можно добавить поддержку нескольких базовых директорий, вести логирование ошибок или даже кэшировать найденные пути.
А вы когда-нибудь создавали свою автозагрузку? Или полностью полагаетесь на Composer?
👉 [|@php_be1]
Мы все ценим Composer, но иногда он не подходит — например, для маленьких проектов, скриптов или наследуемого кода, где Composer изначально не использовался. В таких случаях можно сделать простую, но эффективную автозагрузку самостоятельно.
Приведу простой пример:
spl_autoload_register(function ($class) {
$baseDir = __DIR__ . '/src/';
$classPath = str_replace('\\', '/', $class) . '.php';
$file = $baseDir . $classPath;
if (file_exists($file)) {
require $file;
}
});
Что здесь происходит:
- spl_autoload_register регистрирует анонимную функцию, которая срабатывает при попытке использовать неопределённый класс.
- Класс App\Services\MailService преобразуется в путь src/App/Services/MailService.php.
- Если файл найден — он подключается.
Это очень удобный способ организовать код и избавиться от множества require.
Если нужна большая гибкость — можно добавить поддержку нескольких базовых директорий, вести логирование ошибок или даже кэшировать найденные пути.
А вы когда-нибудь создавали свою автозагрузку? Или полностью полагаетесь на Composer?
👉 [|@php_be1]
Сегодня расскажу, как правильно и безопасно работать с вводом пользователя в 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]
Часто встречаю в коде такой пример:
$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
🗓 15 мая, 20:00 МСК · онлайн · бесплатно
👤 Спикер — Михаил Каморин, Tech Lead Avito, 5 лет на Symfony
Symfony уверенно решает задачу мультиязычности — но что, если переводы живут в БД, а не в yaml-файлах? На вебинаре разберём базовый пример, как «подружить» symfony/translation с динамическими строками — без глубокого погружения во все тонкости компонента.
Что разберём
• Стандартная локализация статических текстов: настройка, plural-формы, fallback-языки.
• Подход к динамическим переводам в БД: таблицы, базовый Doctrine-маппинг.
• Практический пример: сохраним и извлечём строки, посмотрим метрики в Profiler.
Кому полезно
— Middle/Senior PHP-разработчикам, архитекторам и тимлидам, которые строят мульти-язычные сервисы или ищут нетривиальные модели хранения.
Формат — 60 минут концентрированной практики + Q&A без воды.
🔗 Регистрация
Слоты ограничены; участие бесплатное.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Сегодня я хочу рассказать о приёме, который значительно облегчает мне жизнь при отладке в 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]
🛠 Как удобно отлаживать сложные объекты в 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
🗓 15 мая, 20:00 МСК · онлайн
👤 Спикер — Михаил Каморин, Tech Lead Avito
Symfony-проекты часто сталкиваются с задачей мультиязычности. Как локализовать статические строки — понятно, а что делать с динамическими текстами в БД? На вебинаре покажем базовый рабочий маппинг для обоих сценариев.
Что успеем за 60 минут
• Настроим компонент symfony/translation для статических файлов.
• Построим простую схему БД и Doctrine-маппинг для динамических переводов.
• Сохраним, извлечём и отладим строки в Profiler.
• Ответим на живые вопросы в Q&A.
Кому стоит прийти
— Middle/Senior PHP-разработчикам, архитекторам и тимлидам, которым нужны готовые паттерны локализации или нестандартные модели хранения.
⚡️ Слотов осталось мало — регистрация закроется в день мероприятия
🔗 Успейте записаться
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576