es
Feedback

¡No caigas en manos de tramposos! Telemetrio encuentra y marca estos canales 👉 Si quieres ver la etiqueta, suscríbete

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

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

Ir al canal en Telegram

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

Mostrar más

📈 Análisis del canal de Telegram Библиотека пхпшника | PHP, Laravel, Symfony, CodeIgniter

El canal Библиотека пхпшника | PHP, Laravel, Symfony, CodeIgniter (@phpproglib) en el segmento lingüístico de Ruso es un actor destacado. Actualmente la comunidad reúne a 10 463 suscriptores, ocupando la posición 11 707 en la categoría Tecnologías y Aplicaciones y el puesto 60 816 en la región Rusia.

📊 Métricas de audiencia y dinámica

Desde su creación el невідомо, el proyecto ha mostrado un crecimiento acelerado, reuniendo a 10 463 suscriptores.

Según los últimos datos del 27 octubre, 2026, el canal mantiene una actividad estable. En los últimos 30 días la variación de miembros fue de -37, y en las últimas 24 horas de -2, conservando un alto alcance.

  • Estado de verificación: No verificado
  • Tasa de interacción (ER): El promedio de interacción de la audiencia es 16.71%. Durante las primeras 24 horas tras publicar, el contenido suele obtener 7.56% de reacciones respecto al total de suscriptores.
  • Alcance de las publicaciones: Cada publicación recibe en promedio 1 748 visualizaciones. En el primer día suele acumular 791 visualizaciones.
  • Reacciones e interacción: La audiencia responde de forma activa: el promedio de reacciones por publicación es 1.
  • Intereses temáticos: El contenido se centra en temas clave como php, laravel, пхпшника, artisan, api.

📝 Descripción y política de contenido

El autor describe el recurso como un espacio para expresar opiniones subjetivas:
“Все самое полезное для пхпшника в одном канале. По рекламе: @tproger_sales_bot Учиться у нас: clc.to/M561SQ Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5d13cd6fa92100ee6f68b”

Gracias a la alta frecuencia de actualizaciones (últimos datos recibidos el 28 octubre, 2026), el canal mantiene la vigencia y un amplio alcance. La analítica demuestra que la audiencia interactúa activamente con el contenido, lo que lo convierte en un punto de referencia dentro de la categoría Tecnologías y Aplicaciones.

10 463
Suscriptores
-224 horas
-257 días
-3730 días
Archivo de publicaciones
📊 Queue vs Cron Оба инструмента про «выполнить что-то не прямо сейчас». Но они решают разные задачи, и смешивать их не стоит. Cron — планировщик. Он про время. «Запусти это в 03:00». «Запусти каждые 5 минут». Ему всё равно, что именно запускать — он просто триггерит процесс по расписанию. Queue — очередь. Она про события и нагрузку. «Отправь письмо, когда пользователь зарегистрировался». «Обработай 10 000 строк CSV асинхронно». Очередь не знает про время, она знает про задачи. 🔹 Где Cron уместен — Агрегация данных за период (ночные отчёты) — Очистка устаревших записей — Синхронизация с внешним источником по расписанию — Задачи, которые должны выполняться независимо от пользовательской активности 🔹 Где Queue уместен — Всё, что пользователь спровоцировал, но ждать не должен — Задачи с потенциальными ретраями (внешний API может упасть) — Параллельная обработка (несколько воркеров) — Отправка уведомлений, генерация файлов, вебхуки Если ты пишешь cron-задачу, которая ищет записи со статусом "pending" — ты уже строишь очередь. Используй нормальную: Redis + Laravel Horizon, RabbitMQ, SQS, Beanstalkd. Комбинация: cron запускает job, который кладёт задачи в очередь. Это нормально — диспетчер по расписанию и обработчики асинхронно. 🐸 Библиотека пхпшника #элементарный_выбор

✌🏻 У нас две новости — хорошая и плохая! Хорошая: Ваших знаний, скорее всего, хватит, чтобы собрать рабочую демку AI-агента в Colab. 🫡 Плохая: Вы вряд ли выведете его в прод, не обанкротившись на токенах и не слив базу. 🤯 Для защиты от таких сценариев мы полностью пересобрали курс «Разработка AI-агентов». Теперь внутри плотная работа с экономикой ресурсов, дебаг через time-travel в LangGraph, извлечение данных из кривых сканов для RAG и комплаенс по 152-ФЗ.
Если всё ещё сомневаетесь, послушайте голосовое от спикера курса Влада Прошинского, где он объясняет, как правильно тестировать агентов перед релизом.
Программа курса, полный состав спикеров и другие подробности 👈🏻 ВАЖНО! До 5 апреля на курс действует скидка, но свободные места могут закончиться раньше.

⌨️ Топ-вакансий по PHP за неделю PHP разработчик - от 150 000 до 200 000 ₽ - удалёнка Senior Fullstack PHP разработчик - от 250 000 до 350 000 ₽ - удалёнка Lead PHP Developer - до 400 000 ₽ - удалёнка ➡️ Еще больше топовых вакансий — в нашем канале PHP Jobs

📊 Repository Pattern vs Query Builder Repository — это не про «обернуть Eloquent в класс». Это про то, что доменный код не должен знать, откуда берутся данные. Плохой Repository, который можно часто встретить:
class UserRepository {
    public function findActive(): Collection {
        return User::where('status', 'active')->get();
    }
 
    public function findByEmailAndStatus(string $email, string $status): ?User {
        return User::where('email', $email)
                   ->where('status', $status)
                   ->first();
    }
    // ...ещё 40 методов под каждый запрос
}
Это не Repository — это коллекция запросов в обёртке. Домен по-прежнему диктует методы через свои нужды, а репозиторий распухает. Хороший Repository работает с агрегатами и скрывает детали хранения:
interface UserRepository {
    public function findById(UserId $id): ?User;
    public function findByEmail(Email $email): ?User;
    public function save(User $user): void;
    public function remove(User $user): void;
}
Всё остальное — спецификации, критерии, query objects. Или честный Query Builder там, где это не домен. Где Query Builder напрямую оправдан: — Read-модели (CQRS: команды через домен, запросы — прямо в БД) — Отчёты, дашборды, агрегации — там нет смысла гидрировать объекты — Простые CRUD-экраны без доменной логики
// Это нормально для read-модели
$stats = DB::table('orders')
    ->selectRaw('status, COUNT(*) as count, SUM(amount) as total')
    ->groupBy('status')
    ->get();
Пытаться пропустить это через Repository с Order-сущностями — оверинжиниринг. Правило: Repository живёт на границе домена. Если у тебя нет домена, нет смысла в Repository. Если домен есть, Repository скрывает инфраструктуру, а не просто переносит запросы в другой файл. 🐸 Библиотека пхпшника #элементарный_выбор

#байтовый_юмор
#байтовый_юмор

📊 str_contains / str_starts_with vs strpos strpos возвращает int|false. Это создаёт одну конкретную проблему: проверку на false нужно делать строго:
// Классическая ошибка
if (strpos($url, 'admin')) {
    // Не выполнится, если 'admin' в позиции 0
}
 
// Правильно
if (strpos($url, 'admin') !== false) {
    // Окей
}
Этот паттерн !== false живёт в кодбазах как ритуал, смысл которого половина команды уже не помнит. PHP 8.0 дал str_contains, str_starts_with, str_ends_with. Они возвращают bool. Просто bool.
if (str_contains($url, 'admin')) { ... }
if (str_starts_with($route, '/api')) { ... }
if (str_ends_with($file, '.blade.php')) { ... }
Никакого !== false. Никакой магии с позицией 0. Что осталось за strpos: — Нужна позиция вхождения, а не факт наличия — Нужен offset для поиска со смещением — substr_count, substr_replace всё ещё работают с позициями
$pos = strpos($text, '{{');
$end = strpos($text, '}}', $pos);
// Здесь strpos оправдан — тебе нужны числа
Про производительность: str_contains не медленнее strpos на коротких строках. На длинных — профилируй конкретный кейс, не гадай. Короткий вывод: str_contains и компания — это не синтаксический сахар. Это правильный тип возврата для правильного вопроса. 🐸 Библиотека пхпшника #элементарный_выбор

✔️ PHP-тест: Exception handling + PDO транзакции + молчаливая потеря данных Код выглядит аккуратно. Но данные теряются, и никто не знает почему 👇 📦 Задание Есть сервис для обработки платежей. Код покрыт тестами, транзакции есть, ошибки логируются. На проде раз в несколько дней часть платежей пропадает — в БД нет записи, в логах нет ошибок, пользователь уверен что оплатил.
// src/Payment/PaymentService.php
class PaymentService
{
    public function __construct(
        private PDO        $pdo,
        private Logger     $logger,
        private Notifier   $notifier,
    ) {}

    public function process(PaymentDTO $dto): bool
    {
        try {
            $this->pdo->beginTransaction();

            $paymentId = $this->insertPayment($dto);
            $this->updateBalance($dto->userId, $dto->amount);
            $this->insertAuditLog($paymentId, $dto);

            $this->pdo->commit();

            $this->notifier->sendReceipt($dto->userId, $paymentId);

            return true;

        } catch (NotificationException $e) {
            $this->logger->warning('Receipt failed', ['error' => $e->getMessage()]);
            return true;

        } catch (Throwable $e) {
            $this->logger->error('Payment failed', ['error' => $e->getMessage()]);
            $this->pdo->rollBack();
            return false;
        }
    }

    private function insertPayment(PaymentDTO $dto): int
    {
        $stmt = $this->pdo->prepare(
            'INSERT INTO payments (user_id, amount, status) VALUES (?, ?, ?)'
        );
        $stmt->execute([$dto->userId, $dto->amount, 'pending']);
        return (int) $this->pdo->lastInsertId();
    }

    private function updateBalance(int $userId, float $amount): void
    {
        $stmt = $this->pdo->prepare(
            'UPDATE balances SET amount = amount - ? WHERE user_id = ?'
        );
        $stmt->execute([$amount, $userId]);

        if ($stmt->rowCount() === 0) {
            throw new \RuntimeException("Balance record not found for user $userId");
        }
    }

    private function insertAuditLog(int $paymentId, PaymentDTO $dto): void
    {
        // Пишем в отдельную audit БД через отдельное соединение
        $this->auditPdo->prepare(
            'INSERT INTO audit_log (payment_id, user_id, amount) VALUES (?, ?, ?)'
        );
        // ... execute
    }
}
🔹 Задачи — Найти сценарий, при котором платёж коммитится в БД, но return true не доходит до контроллера — и данные считаются потерянными — Объяснить проблему — Предложить исправленную структуру Ставьте → 🔥 если нравится формат. Если нет → 🌚 💬 Решения пишите в комменты под спойлер — сравним подходы.

🧠 array_map vs foreach Многие считают array_map более "функциональным" и современным. Но есть нюанс. Бенчмарк на массиве из 100 000 элементов:
// array_map — ~12ms
$result = array_map(fn($x) => $x * 2, $items);
 
// foreach — ~6ms
$result = [];
foreach ($items as $x) {
    $result[] = $x * 2;
}
foreach в 1.5–2 раза быстрее на больших массивах, потому что array_map создаёт замыкание и имеет overhead на каждый вызов callback. Когда всё равно использовать array_map? Когда важна читаемость, а массив маленький (до ~1000 элементов) — разница незаметна. Не оптимизируйте там, где это не нужно.
// Читаемо и достаточно быстро для небольших коллекций
$emails = array_map(fn($u) => $u->email, $users);
💡 Правило: сначала профилируйте, потом оптимизируйте. Blackfire и Xdebug в помощь. Библиотека пхпшника #vardump

#байтовый_юмор
#байтовый_юмор

😱 Если ваш продукт не умеет отдавать данные в формате, понятном AI-агенту, то вас просто не существует Скрипт не будет кликать по красивым кнопкам в браузере, он уйдёт к конкуренту с нормальным API. Перестроить архитектуру под машинных клиентов — это уже не хайп, а необходимое условие сохранения конкурентоспособности. Как адаптировать продукт и не исчезнуть из выдачи: — интегрировать MCP и A2A-взаимодействие, чтобы агенты могли вас читать; — научиться контролировать стоимость (лимиты, кэш, роутинг между моделями); — настроить AgentOps: трейсинг, логирование и отлов регрессий. Всё это ждёт вас на обновлённом курсе «Разработка AI-агентов». Мы специально сделали фокус на утилитарном инжиниринге и production-ready решениях. Кстати, до 29 марта можно забрать курс с большой скидкой, и стоит поторопиться — мест на потоке всё меньше. Зафиксировать цену и начать деплоить агентов без слива бюджета 👈

 ♻️ Redis-кеш с AI Настроить кеш через Redis несложно. Но зачем копировать код из старого проекта, бояться что-то потерять, когда можно сгенерировать эту часть. Промпт, который закроет этот вопрос:
Ты Senior PHP-разработчик. Сгенерируй модуль кеширования для Laravel с Redis, с учётом всех современных паттернов, устойчивости и тестирования. Требования: Использование Redis через phpredis или predis (с учётом конфигурации в .env) Кеширование с разными TTL для разных типов данных (разделение по Cache Store) 2 сервиса с кешированием: Стратегия cache-aside (чтение из кеша и обновление вручную) Стратегия write-through (автоматическое обновление кеша при записи данных) Обработка инвалидации кеша при изменении данных Кастомная обработка ошибок: Fallback на in-memory или file cache (без исключений при недоступности Redis) Логирование ошибок кеширования с уведомлением Применение circuit breaker и retry паттернов при сете ошибок Redis Защита от слишком частых запросов через кеширование с TTL и expiration для разных кешей Изоляция кеш-слоя с использованием сервисов и репозиториев (не Cache фасад в контроллерах) Настройки в .env и конфигурации кеша Простой и понятный конфиг с разделением кешей для разных типов данных Юнит-тесты с использованием Testcontainers для запуска Redis в Docker Тестирование fallback-механизмов Мокирование с имитацией недоступности Redis Тесты на использование кеша с разными TTL Стек: PHP 8.1+, Laravel 9.x, Redis, PHPUnit, Docker, Testcontainers
Библиотека пхпшника

🧠 PHP-лайфхак Хочешь ловить баги до запуска кода? Используй статический анализ. Это инструмент, который проверяет твой PHP-код на ошибки, несоответствия типам и подозрительные конструкции — без выполнения программы. 🔍 Как это работает 🧩 Установи PHPStan: composer require --dev phpstan/phpstan Запусти анализ: ./vendor/bin/phpstan analyse src --level=max --level=max включает максимально строгую проверку. Можно использовать уровни от 0 до 9 — начни с 5–6, чтобы не утонуть в предупреждениях. ⚡️ Что даёт PHPStan / Psalm 🐞 Находит ошибки типов ещё до запуска кода 🚫 Предупреждает о неиспользуемых переменных и мёртвом коде 🧩 Помогает навести порядок в архитектуре 🔒 Снижает риск багов при рефакторинге 💡 Интеграция с Composer и CI/CD Добавь команду в composer.json: "scripts": { "analyze": "phpstan analyse src --level=max" } Теперь можно запускать проверку просто: composer analyze А в CI — добавить шаг перед деплоем, чтобы ни один коммит с ошибками типов не ушёл в прод. Библиотека пхпшника

⌨️ Топ-вакансий по PHP за неделю PHP Developer (Laravel) - 150 000 - 200 000₽ - офис/гибрид/удалёнка (Ульяновск) Backend-разработчик (PHP) - до 220 000 ₽ - офис/гибрид (Москва) Старший fullstack-разработчик PHP (Laravel) - от 300 000 до 350 000 ₽ - удалёнка ➡️ Еще больше топовых вакансий — в нашем канале PHP Jobs

#байтовый_юмор
#байтовый_юмор

💬 Давайте обсудим К статье на Хабре «Я два месяца платил 300к человеку, который тихо скармливал мои задачи в ChatGPT» уже почти 900 комментов. Что думаете, пишите в комменты? #междусобойчик

📊 readonly properties vs private + getter До 8.1 иммутабельность в value objects эмулировали через private + геттер. Это работало, но создавало шум: конструктор, приватное свойство, метод. Три места ради одной идеи.
// До
class Money {
    private int $amount;
 
    public function __construct(int $amount) {
        $this->amount = $amount;
    }
 
    public function getAmount(): int {
        return $this->amount;
    }
}
readonly убирает весь этот церемониал:
// После
class Money {
    public function __construct(
        public readonly int $amount,
    ) {}
}
Читается как контракт: свойство публично, но записать его можно только один раз при инициализации. Повторная запись → Error, не предупреждение. Когда readonly не подходит: 1. Нужна ленивая инициализация. readonly нельзя присвоить вне конструктора (до PHP 8.4 с хуками). 2. Клонирование с изменением. clone с readonly требует PHP 8.3 (readonly классы + clone в new static). 3. Моки в тестах. Если тест хочет подменить значение readonly-свойства через рефлексию, получит Error. PHP 8.2 добавил readonly классы — все свойства автоматически readonly:
readonly class Coordinates {
    public function __construct(
        public float $lat,
        public float $lng,
    ) {}
}
Хорошо для DTO, value objects, команд и событий. Плохо там, где нужна мутация или частичная инициализация. Правило простое: если объект концептуально иммутабелен → readonly. Если есть хоть одна причина менять состояние после создания → private + логика в методах. 🐸 Библиотека пхпшника #элементарный_выбор

Что действительно ускоряет автозагрузку на проде?
Anonymous voting

🔍 Убийца перфоманса, который можно пропустить в ревью Классика, которую все знают, но продолжают допускать. Особенно в Eloquent. 🔹 Проблема
$orders = Order::all();
 
foreach ($orders as $order) {
    echo $order->user->name; // SELECT * FROM users WHERE id = ? (на каждой итерации!)
}
🔹 Решение — eager loading
$orders = Order::with('user')->get();
// Теперь 2 запроса вместо N+1
🔹 Как поймать в проде Подключите debugbar или telescope в dev-среде. Или логируйте запросы вручную:
DB::listen(function ($query) {
    Log::info($query->sql, $query->bindings);
});
💡 Если видите один и тот же запрос десятки раз в логах — это он. Ищите все места, где обращаетесь к связям внутри цикла. Библиотека пхпшника #vardump

❓ Точки роста PHP-разработчика Наш подписчик спрашивает
«Я PHP-разработчик с опытом 1,5 года. Но ощущаю, что топчусь на месте. Какие навыки стоит развивать, чтобы сдвинуть с мертвой точки через год-два ? Углубляться в фреймворки или лучше прокачивать soft skills?» Алексей, PHP Developer
💬 Делитесь в комментариях: — Какие технические навыки необходимы для роста — Насколько важны фреймворки и архитектура — Какие soft skills действительно ценят P.S. Если хотите задать вопрос, заполните нашу гугл-форму. Это займет 5 минут. #междусобойчик

✔️ PHP-тест: Typed Properties + Lazy Initialization + Объект в статике Баг, который живёт в проде месяцами и проявляется только под нагрузкой 👇 📦 Задание Команда пишет модуль биллинга. Ты написал быстрый класс-обёртку для работы с тарифами. Код прошёл ревью, всё работало на стейджинге. В проде через неделю начались жалобы: у части пользователей неправильно считается стоимость. Причём только в пиковые часы.
// src/Billing/TariffCalculator.php
class TariffCalculator
{
    private static TariffConfig $config;
    private static array $cache = [];

    public static function init(array $rawConfig): void
    {
        self::$config = new TariffConfig($rawConfig);
    }

    public static function calculate(int $userId, int $units): float
    {
        $key = $userId . ':' . $units;

        if (isset(self::$cache[$key])) {
            return self::$cache[$key];
        }

        $price = self::$config->getBasePrice()
            * $units
            * self::$config->getUserMultiplier($userId);

        self::$cache[$key] = $price;

        return $price;
    }

    public static function resetCache(): void
    {
        self::$cache = [];
    }
}

// src/Billing/TariffConfig.php
class TariffConfig
{
    private float $basePrice;
    private array $multipliers;

    public function __construct(array $config)
    {
        $this->basePrice   = (float) $config['base_price'];
        $this->multipliers = $config['multipliers'] ?? [];
    }

    public function getBasePrice(): float
    {
        return $this->basePrice;
    }

    public function getUserMultiplier(int $userId): float
    {
        return $this->multipliers[$userId] ?? 1.0;
    }
}

// bootstrap.php — вызывается один раз при старте воркера
TariffCalculator::init(loadConfigFromDB());

// Где-то в обработчике запроса
$price = TariffCalculator::calculate($user->id, $request->units);
🔹 Задачи — Найти все архитектурные и логические проблемы в коде (их несколько) — Объяснить, почему баг проявляется только под нагрузкой и не воспроизводится на стейджинге — Предложить правильное решение Ставьте → 🔥 если нравится формат. Если нет → 🌚 💬 Решения пишите в комменты под спойлер — сравним подходы.