ru
Feedback
Библиотека пхпшника | PHP, Laravel, Symfony, CodeIgniter

Библиотека пхпшника | PHP, Laravel, Symfony, CodeIgniter

Открыть в Telegram

Все самое полезное для пхпшника в одном канале. По рекламе: @proglib_adv Учиться у нас: https://proglib.io/w/bca892d6 Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5d13cd6fa92100ee6f68b

Больше

📈 Аналитический обзор Telegram-канала Библиотека пхпшника | PHP, Laravel, Symfony, CodeIgniter

Канал Библиотека пхпшника | PHP, Laravel, Symfony, CodeIgniter (@phpproglib) языкового сегмента Русский является активным участником. Сейчас сообщество объединяет 10 703 подписчиков, занимая 11 598 место в категории Технологии и приложения и 61 274 место в регионе Россия.

📊 Показатели аудитории и динамика

С момента создания невідомо проект демонстрирует стремительный рост, собрав аудиторию из 10 703 подписчиков.

Согласно последним данным от 05 июня, 2026, канал показывает стабильную активность. За последние 30 дней изменение числа участников составило -34, а за последние 24 часа — -1, при этом общий охват остаётся высоким.

  • Статус верификации: Не верифицирован
  • Уровень вовлечённости (ER): Средний показатель вовлечённости аудитории составляет 15.28%. В первые 24 часа после публикации контент обычно набирает 9.13% реакций от общего числа подписчиков.
  • Охват публикаций: В среднем каждый пост получает 1 637 просмотров. В течение первых суток публикация набирает 978 просмотров.
  • Реакции и взаимодействия: Аудитория активно поддерживает контент: среднее количество реакций на один пост — 11.
  • Тематические интересы: Контент сосредоточен на ключевых темах, таких как php, laravel, пхпшника, artisan, api.

📝 Описание и контентная политика

Автор описывает ресурс как площадку для выражения субъективного мнения:
Все самое полезное для пхпшника в одном канале. По рекламе: @proglib_adv Учиться у нас: https://proglib.io/w/bca892d6 Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5d13cd6fa92100ee6f68b

Благодаря высокой частоте обновлений (последние данные получены 07 июня, 2026) канал поддерживает актуальность и высокий уровень охвата публикаций. Аналитика показывает, что аудитория активно взаимодействует с контентом, что делает его важной точкой влияния в категории Технологии и приложения.

10 703
Подписчики
-124 часа
-97 дней
-3430 день
Архив постов
✔️ PHP-тест: клон, который мутирует оригинал Пользователь нажал «Повторить заказ». Цены в его старом заказе изменились. 📦 Задание Фича: кнопка «Повторить заказ» в личном кабинете. Копирует предыдущий заказ, применяет промокод, создаёт новый черновик. Оригинал помечается флагом repeated для аналитики. Через неделю — тикет от бухгалтерии: суммы в старых заказах не сходятся с тем, что было при оплате. Проблема только у заказов, которые хотя бы раз «повторяли». Суммы занижены ровно на размер скидки по промокоду.
// src/Order/Order.php
class Order
{
    public function __construct(
        private ?int   $id,
        private int    $userId,
        private array  $items, 
        private string $status,
        private bool   $repeated = false,
    ) {}

    public function getId(): ?int      { return $this->id; }
    public function getItems(): array  { return $this->items; }
    public function getStatus(): string { return $this->status; }

    public function resetForRepeat(): void
    {
        $this->id       = null;
        $this->status   = 'draft';
        $this->repeated = false;
    }

    public function markAsRepeated(): void
    {
        $this->repeated = true;
    }

    public function calculateTotal(): int
    {
        return array_sum(array_map(
            fn(OrderItem $i) => $i->getSubtotal(),
            $this->items
        ));
    }
}

// src/Order/OrderItem.php
class OrderItem
{
    public function __construct(
        private int $productId,
        private int $qty,
        private int $price,
    ) {}

    public function getProductId(): int { return $this->productId; }
    public function getQty(): int       { return $this->qty; }
    public function getPrice(): int     { return $this->price; }

    public function getSubtotal(): int
    {
        return $this->qty * $this->price;
    }

    public function applyDiscount(int $percent): void
    {
        $this->price = (int) round(
            $this->price * (1 - $percent / 100)
        );
    }
}

// src/Order/RepeatOrderHandler.php
class RepeatOrderHandler
{
    public function __construct(
        private OrderRepository $orders,
        private PromoService    $promo,
    ) {}

    public function handle(int $originalId, ?string $promoCode): Order
    {
        $original = $this->orders->findById($originalId);

        $copy = clone $original;
        $copy->resetForRepeat();

        if ($promoCode !== null) {
            $discount = $this->promo->resolve($promoCode);

            foreach ($copy->getItems() as $item) {
                $item->applyDiscount($discount->percent);
            }
        }

        $this->orders->save($copy);

        $original->markAsRepeated();
        $this->orders->save($original);

        return $copy;
    }
}

// src/Repository/OrderRepository.php
class OrderRepository
{
    public function __construct(private PDO $pdo) {}

    public function save(Order $order): void
    {
        if ($order->getId() === null) {
            $this->insert($order);
        } else {
            $this->update($order);
        }
    }

    private function update(Order $order): void
    {
        $this->pdo->prepare(
            'UPDATE orders SET status = ?, repeated = ? WHERE id = ?'
        )->execute([$order->getStatus(), (int) $order->isRepeated(), $order->getId()]);

        $this->pdo->prepare('DELETE FROM order_items WHERE order_id = ?')
            ->execute([$order->getId()]);

        foreach ($order->getItems() as $item) {
            $this->pdo->prepare(
                'INSERT INTO order_items (order_id, product_id, qty, price) VALUES (?, ?, ?, ?)'
            )->execute([$order->getId(), $item->getProductId(), $item->getQty(), $item->getPrice()]);
        }
    }
}
🔹 Задачи — Объяснить, каким образом цены в оригинальном заказе оказались изменены в базе — Исправить код так, чтобы оригинал гарантированно не мутировал Ставьте → 🔥 если нравится формат. Если нет → 🌚 💬 Решения пишите в комменты под спойлер — сравним подходы.

💡 Затрагиваемые отношения Eloquent Laravel автоматически обновляет updated_at в ManyToMany отношениях, а также поставляется
💡 Затрагиваемые отношения Eloquent Laravel автоматически обновляет updated_at в ManyToMany отношениях, а также поставляется с методом setTouchedRelations для ручного обновления связанных моделей в отношениях OneToOne и OneToMany. 🐸 Библиотека пхпшника #vardump

Письмо ушло, но воркер упал до того как пометил job выполненной. Job запустилась повторно, что получит пользователь?
Anonymous voting

🧑‍💻 Приглашаем на открытый урок курса «PHP-разработчик. Продвинутый уровень» 19 мая в 20:00 — Работа с очередями в Laravel:
🧑‍💻 Приглашаем на открытый урок курса «PHP-разработчик. Продвинутый уровень» 19 мая в 20:00 — Работа с очередями в Laravel: от настройки до решения типичных проблем Разберём, как очереди помогают ускорить приложение и вынести тяжёлые задачи в фон без потери стабильности. Обсудим настройку и обработку задач, типичные ошибки, повторы при сбоях, защиту от дублирования и мониторинг выполнения. Вы поймёте, как работают фоновые процессы в Laravel, научитесь правильно настраивать очереди и делать приложение быстрее и надёжнее. 🚀Открытый урок проходит в преддверии старта курса «PHP-разработчик. Продвинутый уровень» 19 мая в 20:00 МСК. Регистрация: https://clc.to/v1jqRw Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru

🔽 Ловим тормозные запросы до того, как это сделает прод Метод whenQueryingForLongerThan позволяет задать порог в миллисекундах и среагировать моментально: кинуть алерт в Slack, залогировать или просто позвать автора запроса на кофе.
// AppServiceProvider::boot()

DB::whenQueryingForLongerThan(500, function (Connection $connection, QueryExecuted $event) {
    Log::warning('Slow query detected', [
        'sql'  => $event->sql,
        'time' => $event->time,
    ]);

    // Notification::send(...);
});
⏱️ Порог считается для суммарного времени всех запросов на соединении, а не для одиночного (для точечного мониторинга есть DB::listen()).

📌 backup PostgreSQL с минимальной нагрузкой на прод Разберём эффективный способ бэкапа PostgreSQL с помощью pg_basebackup + реплики. Сценарий: есть продовый PostgreSQL и настроенная горячая реплика (streaming replication). Зачем использовать реплику для бэкапа? ▪️ Причины — На проде бэкап может замедлить отклик приложения. — Реплика отличный способ разгрузить основной сервер. — Бэкап с pg_basebackup возможен только на стопнутой БД или через репликацию. ▪️ Как сделать
pg_basebackup -h replica.host -U repl_user -D /backup/pg -F tar -z -P
▪️ Флаги -h — адрес реплики -U — пользователь с правами репликации -D — куда класть бэкап -F tar -z — формат архива и сжатие -P — прогресс в консоли А ещё можно добавить в cron и получить стабильный ночной бэкап.

🔥 Знакомьтесь с экспертом Proglib.academy: Эмиль Сатаев Эмиль — эксперт с 8-летним опытом в разработке, который специализиру
🔥 Знакомьтесь с экспертом Proglib.academy: Эмиль Сатаев Эмиль — эксперт с 8-летним опытом в разработке, который специализируется на внедрении LLM и агентных подходов в реальные коммерческие сервисы. Он точно знает, как проектировать архитектуру так, чтобы ИИ-функции работали стабильно в связке с внешними системами. 🏃‍♀️ Уже 14 мая Эмиль проведет открытый вебинар! Обсудим самую «больную» тему: «Почему AI-продукты на базе LLM ломаются и как сделать, чтобы работало». 🗓 Когда: 14 мая в 19:00 (Мск) Почему Эмиля стоит послушать: 🟣 8+ лет в разработке (Backend и Frontend)
Прошел путь от фулстека до Backend Platform Developer в SMIT.Studio.
🟣 Международный исследовательский опыт
Работал исследователем в Институте ИИ НИУ ВШЭ и в Национальном университете Сингапура (NUS).
🟣 Преподаватель-практик
Ведет семинары в НИУ ВШЭ, в том числе по проектированию и разработке агентских систем.
🟣 Мастер интеграции AI в Backend
Его главная суперсила — умение правильно встраивать LLM через API, выстраивать workflow и агентную логику в сложных распределенных системах.
🔗 Зарегистрироваться на вебинар

🧠 LLPhant: LangChain для PHP-разработчиков Если нужно прикрутить LLM к проекту, а городить мост на Python в виде отдельного сервиса не хочется — LLPhant закрывает эту задачу одной либой. Это единый интерфейс к OpenAI, Anthropic, Mistral, LM Studio и локальным моделям через Ollama.
// Сегодня OpenAI
$chat = new OpenAIChat();
$response = $chat->generateText('Столица Франции?');

// Завтра — локальная модель
$config = new OllamaConfig();
$config->model = 'llama2';
$chat = new OllamaChat($config);
Что внутри: — полноценный RAG-пайплайн: чтение PDF/Word, чанкинг, эмбеддинги, поиск; — векторные хранилища на любой вкус — pgvector, Redis, Elastic, Qdrant, Milvus, Pinecone; — стриминг ответов, подсчет токенов, vision для картинок; — function calling — описываешь тулзы PHP-классами, модель сама решит когда дернуть. Для смены провайдера нужно переписать две строки в конфиге (а не половину сервиса). 🔗 Подробнее Библиотека пхпшника

⚡️ Магия curl Сервис отвечает 500-кой, а вы не понимаете — проблема в сети, DNS, SSL или бэкенд лёг? Прежде чем лезть в логи и разворачивать Wireshark, попробуйте curl -w и получите полный таймлайн запроса за секунду. 🔹 Зачем это нужно — Разбивает запрос на фазы: DNS, TCP-коннект, TLS-хендшейк, ожидание первого байта, передача данных. — Моментально показывает, где именно bottleneck — на уровне сети или приложения. — Работает везде: на проде, в контейнере, на CI-раннере. 🔹 Как использовать — Полный таймлайн запроса:
curl -o /dev/null -s -w "\n  DNS: %{time_namelookup}s\n  TCP: %{time_connect}s\n  TLS: %{time_appconnect}s\n  TTFB: %{time_starttransfer}s\n  Total: %{time_total}s\n" https://your-api.com/health
— Если time_namelookup высокий, проблема в DNS, смотрите резолвер. — Если между time_connect и time_appconnect большой разрыв, тормозит TLS, проверяйте сертификаты. — Если time_starttransfer зашкаливает при нормальном коннекте, бэкенд думает слишком долго. — Удобно завернуть в алиас и дёргать по крону для бедняцкого мониторинга latency. 💡 Про-тип: сохраните шаблон в файл и вызывайте через curl -w имя_файла. Не придётся каждый раз гуглить формат переменных.

📊 Аналитика поведения: 5 инструментов, которые стоит знать Гуглишь «best analytics tools» и получаешь кашу из BI-дашбордов, product analytics и session replay в одной куче. Разложу по полочкам именно поведенческую аналитику и конкурентную разведку — то, что реально нужно, когда задача «понять, почему юзеры не конвертятся». Hotjar — безопасный дефолт. Хитмапы, записи сессий, фидбек-виджеты. Порог входа минимальный, поэтому его ставят первым и часто на нём остаются. Если нужно быстро показать продакту «вот тут юзеры отваливаются» — закроет задачу. Но если серьёзно копаете конверсии, ему начинает не хватать глубины. Mouseflow — для тех, кто реально сидит в записях и воронках. Friction score, form analytics, 6 типов хитмап (включая geo и live). По CRO и e-commerce — пожалуй, самый сильный вариант. Подвох: кредитные лимиты и капы на объём сессий начинают кусаться при росте трафика. Crazy Egg — максимально простой. Хитмапы, скроллмапы, оверлеи. Не нужна глубокая аналитика, нужно за 15 минут понять, куда кликают и докуда скроллят — это оно. Kissmetrics — другая лига. Event-level аналитика, retention, lifecycle. Заточен под SaaS с логин-зоной, где важен путь конкретного юзера, а не агрегированные хитмапы. Overhead на внедрение ощутимый, комьюнити вокруг инструмента тоньше, чем у Hotjar. Similarweb — вообще не про ваш сайт, а про чужие. Бенчмарки трафика, каналы, доли рынка. Цифры направляющие, не абсолютные — относитесь как к компасу, не как к GPS.

🧹 Git-команда, которая спасёт ваш репозиторий от мусора Проблема: вы удалили ветки, сделали git reset, отменили мёржи, но репозиторий почему-то весит всё больше. git clone на новом месте занимает вечность. Куда уходит место? Дело в том, что Git — барахольщик. Он хранит все объекты: старые блобы, недостижимые коммиты, забытые stash'ы. Даже то, что вам давно не нужно. 💡 Решение: git gc и его старший брат git gc --aggressive Рассмотрим все все возможности git gc. 1️⃣ Сколько мусора накопилось
git count-objects -vH
Обратите внимание на size-pack — это реальный вес вашего репо. 2️⃣ Самые тяжёлые объекты в истории
git rev-list --objects --all \
  | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
  | awk '/^blob/ {print $3, $4}' \
  | sort -rn \
  | head -10
Часто находятся артефакты сборки, дампы БД или случайно закоммиченные .jar на 200 МБ 😬 3️⃣ Запустите агрессивную сборку мусора
git gc --aggressive --prune=now
--aggressive заставляет Git перепаковать объекты с нуля, а --prune=now удаляет недостижимые объекты немедленно, не дожидаясь дефолтных двух недель. 4️⃣ Сравните результат
git count-objects -vH
На живых проектах с историей в 2+ года разница бывает в разы. ⚠️ --prune=now безвозвратно удалит объекты, на которые нет ссылок. Если вы планировали восстановить что-то через git reflog — сделайте это до запуска.

✔️ PHP-тест: Идемпотентность, которой нет Пользователь нажал «Оплатить» один раз. Деньги списались дважды. 📦 Задание Фича: интеграция с платёжным шлюзом. Платёж создаётся на бэке, пользователь редиректится на страницу шлюза, после оплаты шлюз дёргает webhook. По webhook'у выдаётся доступ к продукту. Жалобы начались через две недели после релиза. Только у части пользователей, только в часы пик. У некоторых списывалось дважды, у других доступ не выдавался вовсе.
// src/Payment/WebhookHandler.php
class WebhookHandler
{
    public function __construct(
        private PaymentRepository $payments,
        private OrderRepository   $orders,
        private AccessService     $access,
        private Mailer            $mailer,
    ) {}

    public function handle(array $payload): void
    {
        $externalId = $payload['payment_id'];
        $status     = $payload['status'];

        if ($status !== 'success') {
            return;
        }

        $payment = $this->payments->findByExternalId($externalId);

        if ($payment === null) {
            return;
        }

        $order = $this->orders->findById($payment->orderId);

        if ($order->status === 'paid') {
            return;
        }

        $this->orders->markAsPaid($payment->orderId);
        $this->access->grantForOrder($order);
        $this->mailer->sendReceipt($order);
    }
}

// src/Repository/OrderRepository.php
class OrderRepository
{
    public function __construct(private PDO $pdo) {}

    public function findById(int $id): Order
    {
        $stmt = $this->pdo->prepare(
            'SELECT * FROM orders WHERE id = ?'
        );
        $stmt->execute([$id]);
        return Order::fromRow($stmt->fetch(PDO::FETCH_ASSOC));
    }

    public function markAsPaid(int $orderId): void
    {
        $stmt = $this->pdo->prepare(
            'UPDATE orders SET status = ? WHERE id = ?'
        );
        $stmt->execute(['paid', $orderId]);
    }
}
🔹 Задачи — Объяснить, как именно возникает двойное списание при одном нажатии пользователя — Исправить WebhookHandler::handle Ставьте → 🔥 если нравится формат. Если нет → 🌚 💬 Решения пишите в комменты под спойлер — сравним подходы.

🗓 14 мая в 19:00 (Мск) встречаемся в онлайне. Тема: Почему AI-продукты на базе LLM ломаются и как сделать, чтобы работало. В кружке выше Эмиль Сатаев рассказал, какие именно проблемы с LLM в проде будем разбирать. Что в программе:
- Разберем реальные кейсы стартапов и ограничения LLM. - Обсудим рабочие архитектуры: RAG, human-in-the-loop, контроль качества. - Ответим на ваши вопросы и разберем кейсы участников.
🎁 Бонусы: в конце вебинара подарим промокод на скидку 10.000 ₽ на курсы и разыграем подписки на полезные AI-сервисы. 👉 Зарегистрироваться на вебинар

Видеосообщение00:40

🔼 Улучши UX одним методом При создании опций для CLI-приложений можно улучшить UX, реализовав автозаполнение для пользовател
🔼 Улучши UX одним методом При создании опций для CLI-приложений можно улучшить UX, реализовав автозаполнение для пользователя. Это можно сделать с помощью метода anticipate, предоставляемого Laravel 🚀 Библиотека пхпшника #vardump