PHP-BE1
310 subscribers
337 photos
11 videos
19 files
618 links
Канал по PHP, полезный и интересный контент для всех уровней.
По вопросам сотрудничества @cyberJohnny
Download Telegram
🔥 Laravel Telemetry 🔥

Команда Laravel объявляет о включении во фреймворк Telemetry — нового модуля для сбора анонимной статистики об использовании фреймворка. Это поможет анализировать популярные фичи, оптимизировать производительность и сделать Laravel ещё лучше! Telemetry будет включена по умолчанию и собирать такие данные, как версия PHP, используемые пакеты, время выполнения запросов и частота ошибок.

Если вдруг вы не хотите участвовать в улучшении Laravel, всегда можно отключить сбор данных через env-переменную TELEMETRY_ENABLED=false.
@php_be1
Сегодня я хочу поделиться с вами простым и удобным приемом, который помогает поддерживать порядок в больших PHP-проектах — это использование кастомных коллекций вместо обычных массивов.

Если вы когда-либо передавали массивы объектов в методы или возвращали их из них, то, вероятно, сталкивались с ситуацией, когда неясно, что именно содержится в массиве. А потом кто-то мог передать туда строку или null — и вот вам, баги.

Я начал использовать свои классы коллекций. Вот простой пример:

class UserCollection
{
/** @ var User[] */
private array $users = [];

public function __construct(array $users = [])
{
foreach ($users as $user) {
$this->add($user);
}
}

public function add(User $user): void
{
$this->users[] = $user;
}

public function all(): array
{
return $this->users;
}

public function filterByActive(): self
{
return new self(array_filter($this->users, fn(User $u) => $u->isActive()));
}

// и так далее
}

Теперь везде, где раньше использовался массив User[], я применяю UserCollection. Это сразу дает:

- типизацию (и защиту от случайных ошибок),
- автодополнение в IDE,
- методы прямо в коллекции (например, filterByActive, sortByName, first() и т.д.),
- более чистые и понятные сигнатуры методов.

Это похоже на коллекции из Laravel, но я использую это везде, даже в небольших проектах без фреймворков. Такие объекты делают код более чистым, устойчивым и легче читаемым.

Попробуйте в одном из ваших проектов заменить массивы объектов на такие коллекции — и вы удивитесь, как стало лучше.

👉 [|@php_be1]
This media is not supported in your browser
VIEW IN TELEGRAM
Анонс Laravel Wayfinder
Генерация TypeScript-функций для ваших Laravel-контроллеров и маршрутов
https://github.com/laravel/wayfinder
@php_be1
Сегодня я расскажу, как я упростил настройку и запуск проектов на Laravel с помощью кастомной команды Make.

Когда ты постоянно работаешь с Laravel, такие команды, как php artisan migrate, npm run dev, php artisan serve, php artisan key:generate становятся рутиной. А если у тебя несколько проектов, путаницы не избежать.

Я решил, что это невыносимо.

Поэтому я создал простую команду в Makefile, которая за считанные секунды поднимает проект в нужной последовательности. Вот пример:

up:
@cp .env.example .env || true
@php artisan key:generate
@composer install
@npm install
@php artisan migrate
@php artisan db:seed
@npm run dev
@php artisan serve

Теперь я просто пишу make up — и Laravel запускается 🚀

Можно добавить и другие команды: make test, make down, make fresh, make lint, и каждый проект будет управляться по единому сценарию. Это экономит много времени.

💡 Совет: обязательно ставь @ перед командами — так терминал не будет засорён выводом строк Makefile.

👉 @php_be1
Новый метод whereAttachedTo() в Laravel 12.7 для получения записей из отношения belongsToMany.
@php_be1
Сегодня я расскажу вам о возможности PHP, которую многие либо не знают, либо забывают использовать — это деструктуризация массива. И зря!

Смотрите, вместо привычного способа:

$user = getUser(); // ['name' => 'Ivan', 'email' => 'ivan@example.com']
$name = $user['name'];
$email = $user['email'];

Можно сделать так:

['name' => $name, 'email' => $email] = getUser();

Код стал более чистым, коротким и понятным. Особенно приятно, когда возвращается ассоциативный массив — не нужно писать вручную много $data['ключ'].

Или с обычными массивами:

[$id, $name, $email] = getUserArray(); // [1, 'Ivan', 'ivan@example.com']

Деструктуризация массива работает с любой нумерацией — главное, чтобы структура совпадала.

💡 Я часто использую это в контроллерах, в тестах и при разборе конфигураций. Это удобно и читаемо.
Привет!

Мы — основатели KTS, IT–компании со штатом в 170+ специалистов, которая создает цифровые продукты для бизнеса с 2015 года.

Недавно мы запустили канал, в котором простым языком рассказываем о том, как бизнес пользуется ИИ-агентами, и объясняем, как они устроены изнутри.

Этот канал будет про:
– кейсы внедрения AI крупными компаниями и стартапами по всему миру;
– то, как мы сами внедряем AI в работу компании и что делаем для российских клиентов;
– устройство AI-агентов с упором на бизнес-эффект.

Подпишись () и черпай полезный опыт!

@php_be1

https://t.me/inside_ai_tech
Релизы PHP 8.4.6 и 8.3.20
https://www.php.net/ChangeLog-8.php

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

@php_be1
⚡️Laravel — удобный PHP-фреймворк, а его возможности выходят далеко за рамки классической веб-разработки. Хотите увидеть, как он помогает автоматизировать реальные процессы?

На бесплатном вебинаре 16 апреля в 20:00 мск покажем, как с помощью Laravel и Telegram Bot API создать Telegram-бота для дистанционного полива цветов. Подключим IoT-устройства, разберём работу с MQTT и визуализируем данные через Grafana.

Вы узнаете, как использовать Laravel в IoT-сценариях, управлять устройствами через Telegram, собирать и отображать метрики, а также получите представление о возможностях Arduino на примере ESP-8266.

👉Регистрируйтесь и получите скидку на большое обучение «Framework Laravel»: https://clck.ru/3LLvTd

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🛠 Как записывать SQL-запросы только в случае ошибок

Часто сталкиваюсь с ситуацией: ошибка 500 в продакшене, и непонятно, что именно пошло не так. Особенно если это связано с ошибкой в SQL-запросе. Логировать все SQL-запросы — это слишком много и создает лишний шум. Но логировать только при исключениях — это отличное решение!

🔍 Решение

Добавьте следующий код в AppServiceProvider:

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

public function boot()
{
DB::listen(function ($query) {
if (app()->bound('exception.logged')) {
Log::channel('sql')->debug($query->sql, $query->bindings);
}
});

app()->singleton('exception.logged', function () {
return true;
});

app()->error(function (\Throwable $e) {
app()->instance('exception.logged', true);
});
}

🔐 Пояснение
- При каждом SQL-запросе мы проверяем, возникло ли исключение.
- Если да — записываем SQL.
- Используем отдельный лог-канал sql, чтобы не загромождать основной laravel.log.

👉 Создайте в config/logging.php канал sql, направьте его в отдельный файл, например storage/logs/sql.log.

Теперь, если в продакшене произойдет ошибка, вы увидите, какой SQL-запрос был выполнен перед ней. Это значительно упрощает диагностику проблем.
Сегодня мы обсудим типы данных в PHP и правильное их использование в вашем проекте.

🧠 Преимущества строгой типизации в PHP

С выходом PHP 7 появилась возможность указывать типы аргументов и возвращаемых значений. В PHP 8 требования стали ещё строже. Однако многие всё ещё игнорируют эту возможность — и это неправильно!

Вот пример. Допустим, у вас есть функция:

function calculateTotal($price, $quantity) {
return $price * $quantity;
}

Теперь тот же код с указанием типов:

function calculateTotal(float $price, int $quantity): float {
return $price * $quantity;
}

Преимущества второго варианта:
- Автоматическая проверка типов во время выполнения
- IDE подсказывает, если передаются неправильные значения
- Код становится самодокументируемым
- Проще проводить тестирование

🔐 Мой совет: включите строгий режим в начале всех ваших файлов:

declare(strict_types=1);

Это заставит PHP работать с более строгой типизацией и поможет выявлять ошибки ещё до выполнения кода.

💬 Используете ли вы строгую типизацию? Или по-прежнему пишете $data = getData(); и надеетесь, что получите ожидаемое значение?

Поделитесь своим опытом в комментариях👇

👉 [|@php_be1]
В Laravel 12.9 добавлен мемоизированный драйвер кэша, который запоминает значения выбранные из основного кэша и сохраняет их в памяти на время выполнения. Проще говоря Кэш для Кэша :)
https://laravel.com/docs/12.x/cache#cache-memoization

@php_be1
Рост нагрузки, стоимость инфраструктуры и ожидания пользователей — всё растёт. А что насчет производительности ваших сервисов?

21–25 апреля пройдет Podlodka PHP Crew (https://podlodka.io/phpcrew?utm_campaign=main_php_crew_6&utm_source=telegram&utm_medium=paid&utm_content=laravel_it)— онлайн-конференция, где дают практические советы по реализации оптимизации.

Podlodka PHP Crew — это практичные конференции для PHP-разработчиков. Формат — утро и вечер, удобно для жизни и работы.

Что в программе:

• Павел Вирский (Ozon) — расскажет, как подойти к горизонтальному масштабированию PHP-приложений: с чего начать, что точно изменится в архитектуре и какие профиты вы получите от балансировки трафика 🧠

• Олег Мифле (Altenar) — покажет, как индексы в БД могут навредить, и что делать, когда “оптимизация” приводит к регрессу производительности 💥

• Ярослав Тарасов (Skyeng) — проведёт разбор оптимизации Symfony-приложения через RoadRunner: от архитектуры до конкретных замеров ⚙️

• Александр Макаров (Yii, Twindo) — расскажет о низкоуровневой оптимизации PHP: от мелких улучшений до AI, который сам оптимизирует ваш код 🧩

🎯 Всё это — для того, чтобы применить знания сразу.

Зарегистрироваться: https://podlodka.io/phpcrew (https://podlodka.io/phpcrew?utm_campaign=main_php_crew_6&utm_source=telegram&utm_medium=paid&utm_content=laravel_it)

@php_be1
Добавлен хелпер uri

@php_be1
🚀 Почему пользователи платят $30 за простой конвертер картинок? Давайте разберемся.

Кирилл из комьюнити создал простой продукт всего за один месяц, внедрив метод, которой уже принес результат.

Как он это сделал:
1️⃣ Анализ спроса: через поисковые запросы он увидел, что много людей ищут конвертацию «HEIC to JPG».
2️⃣ Фокус на главном: удалил всё лишнее, оставив только функцию конвертации в один клик.
3️⃣ Скорость внедрения: за 30 дней сделал запуск без перфекционизма.

Что из этого получилось:
— Доход $500 в месяц с тенденцией роста.
— Более $10K заработано на конвертере.
— $0 на рекламу, всего $40 в месяц на сервер.

Выводы:
— Люди платят за удобство, даже если есть бесплатные аналоги.
— Продукт функционирует автоматически с минимальной поддержкой.
— Быстрая и экономичная проверка идеи может быть успешной.

Наши успехи:
— Более 400 запусков по этой методике.
— Некоторые продукты уже набрали от 50К до 100К+ пользователей.

👉 Присоединяйтесь к @its_capitan — следите за процессом разработки, продвижения и узнайте, сколько можно заработать на таких микро-продуктах.

@php_be1
Аутентификация на основе cookies с помощью Laravel Sanctum
Пошаговое руководство по настройке аутентификации на основе cookies с помощью Laravel Sanctum. В процессе мы объясним логику каждого шага и покажем, как настроить Postman. Кроме того, мы рассмотрим наиболее распространенные проблемы, связанные с CORS.
https://habr.com/ru/companies/otus/articles/902080/

@php_be1
Выпуск СУБД MySQL 9.3.0

Компания Oracle сформировала новую ветку СУБД MySQL 9.3.0. Сборки MySQL Community Server 9.3.0 подготовлены для всех основных дистрибутивов Linux, FreeBSD, macOS и Windows. В соответствии с внедрённой в 2023 году новой моделью формирования релизов, MySQL 9.3 отнесён к веткам "Innovation". Innovation-ветки рекомендованы для тех, кто хочет раньше получать доступ к новой функциональности, публикуются каждые 3 месяца и поддерживаются только до публикации следующего значительного релиза (например, после появления ветки 9.3 прекращена поддержка ветки 9.2). Летом планируют сформировать LTS-релиз 9.4, рекомендованный для внедрений, которым необходима предсказуемость и длительное сохранение неизменного поведения. Следом за LTS-веткой будет сформирована новая Innovation-ветка - MySQL 10.0.

https://www.opennet.ru/opennews/art.shtml?num=63106

@php_be1
Открытый вебинар «Почему стоит выбрать Symfony для нового проекта» в OTUS

📅 29 апреля, 20:00 МСК · онлайн · бесплатно
👤 Спикер — Михаил Каморин

Кто ведёт
• Tech Lead в Avito
• 20 + лет в разработке (10 лет B2B, 4 года B2C)
• 10 + лет на PHP, 5 лет — на Symfony
• Автор двух RAD‑движков (Laravel + Symfony), запущенных в 10 + прод‑проектах
• Выпускник ВМК МГУ, член ПК Podlodka PHP Crew

Symfony — ядро экосистемы PHP. Разберём, как фреймворк помогает запускать и поддерживать продукты с горизонтом 5 + лет.

Ключевые вопросы
• Модульность — 25 + компонентов подключаются по мере надобности
• Гибкость — DI‑контейнер переопределяет сервисы без боли
• Стабильность — LTS 3 года, минорные версии совместимы назад
• Speed‑toolkit — Symfony CLI, Flex, автоконфигурация, Profiler

Кому полезно
— Middle/Senior PHP‑разработчикам, архитекторам и тимлидам, которым нужны строгие аргументы «за» Symfony.

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

Участие бесплатное. Места ограничены. Регистрируйтесь.

https://clck.ru/3LaSdQ

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Сегодня я расскажу, как удобно осуществлять логирование в 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?