// ❌
class OrderService {
public function create(Request $request): Order {
return Order::create([
'user_id' => $request->user()->id,
'amount' => $request->amount,
]);
}
}
// ✅
class OrderService {
public function create(int $userId, float $amount): Order {
return Order::create([
'user_id' => $userId,
'amount' => $amount,
]);
}
}
Сервис не должен знать что такое HTTP. Он принимает данные, а не запрос. Протестировать первый вариант — боль. Второй вызываешь с двумя числами.
Библиотека пхпшника
#vardump
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22💯6👏1🤩1
Forwarded from Библиотека собеса по PHP | вопросы с собеседований
Классический баг, который ломает прод и не воспроизводится локально 👇
📦 Задание
Команда добавила preloading в production для ускорения.
Через день в логах появились странные ошибки: у разных пользователей в одном запросе перемешиваются данные — кто-то видит чужие настройки, кто-то получает null там, где не должен.
На dev-машинах не воспроизводится. Найдите проблему в коде:
// preload.php
require_once 'src/Config.php';
require_once 'src/UserContext.php';
require_once 'src/RequestPipeline.php';
// config/app.php
class Config
{
private static array $data = [];
private static bool $loaded = false;
public static function load(string $env): void
{
if (self::$loaded) {
return;
}
self::$data = parse_ini_file("config/{$env}.ini");
self::$loaded = true;
}
public static function get(string $key): mixed
{
return self::$data[$key] ?? null;
}
}
// src/UserContext.php
class UserContext
{
private static ?array $current = null;
public static function set(array $user): void
{
self::$current = $user;
}
public static function get(): ?array
{
return self::$current;
}
public static function clear(): void
{
self::$current = null;
}
}
// src/RequestPipeline.php
class RequestPipeline
{
private static array $middlewareResults = [];
public static function addResult(string $key, mixed $value): void
{
self::$middlewareResults[$key] = $value;
}
public static function getResult(string $key): mixed
{
return self::$middlewareResults[$key] ?? null;
}
public static function reset(): void
{
self::$middlewareResults = [];
}
}
// public/index.php
Config::load($_ENV['APP_ENV'] ?? 'production');
$user = Auth::check($_SERVER['HTTP_AUTHORIZATION'] ?? '');
UserContext::set($user);
RequestPipeline::addResult('ip', $_SERVER['REMOTE_ADDR']);
RequestPipeline::addResult('ua', $_SERVER['HTTP_USER_AGENT'] ?? '');
$app->handle(ServerRequest::fromGlobals());
🔹 Задачи
— Объяснить, почему при preloading статические свойства классов ведут себя иначе, чем без него, и как это связано с жизненным циклом worker-процесса.
— Объяснить, чем классы отличаются по характеру утечки
— Предложить архитектурное решение: как правильно управлять request-scoped состоянием в long-running процессах
Ставьте → 🔥 если нравится формат. Если нет → 🌚
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍2❤1👏1
Если необходимо распределить трафик между несколькими UDP-серверами, то решение можно найти в книге «Nginx Cookbook: Advanced Recipes for High-performance Load Balancing» автор показывает использование модуля stream с параметром udp для балансировки нагрузки на уровне транспортного слоя.
Пример кода
stream {
upstream ntp {
server ntp1.example.com:123 weight=2;
server ntp2.example.com:123;
}
server {
listen 123 udp;
proxy_pass ntp;
}
}Преимущества
— Поддержка балансировки для UDP-сервисов.
— Гибкая настройка весов серверов.
— Резервирование серверов для повышения надёжности.
Еще больше полезных книг — в нашем канале @progbook
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤2🔥2
Самый востребованный навык в ИТ в 2026-м — навык создания ИИ-агентов
Мы полностью переработали курс «Разработка AI-агентов» под реалии 2026 года. Никакой долгой теории — с самого начала пишем код. Обучать и делиться набитыми шишками будут эксперты-практики из Газпромбанка, Альфа-Банка и других бигтехов.
В программе:
— архитектура автономных систем с тестированием, ReAct-циклами и контролем токенов;
— практическая работа с актуальными фреймворками LangGraph, AutoGen, MCP и CrewAI;
— настройка продвинутого RAG для парсинга документов и точного поиска;
— внедрение решений с учётом действующего законодательства (152-ФЗ);
— дипломная работа, за основу которой можно взять свой рабочий проект или задачу, которую предложим мы.
Эксперты поделятся инсайтами из реального продакшна — тем, о чём вам никогда не расскажет ни одна нейросеть.
Ах да, чуть не забыли! Дарим промокодAGENTSWEB на скидку 10 000 рублей и два курса сверху при покупке до 15 марта 🎁
→ Стать AI-инженером
Мы полностью переработали курс «Разработка AI-агентов» под реалии 2026 года. Никакой долгой теории — с самого начала пишем код. Обучать и делиться набитыми шишками будут эксперты-практики из Газпромбанка, Альфа-Банка и других бигтехов.
В программе:
— архитектура автономных систем с тестированием, ReAct-циклами и контролем токенов;
— практическая работа с актуальными фреймворками LangGraph, AutoGen, MCP и CrewAI;
— настройка продвинутого RAG для парсинга документов и точного поиска;
— внедрение решений с учётом действующего законодательства (152-ФЗ);
— дипломная работа, за основу которой можно взять свой рабочий проект или задачу, которую предложим мы.
Эксперты поделятся инсайтами из реального продакшна — тем, о чём вам никогда не расскажет ни одна нейросеть.
Запись первого открытого вебинара, на котором мы вместе с руководителем AI-направления в Альфа-Банке Полиной Полуниной пилили агента в прямом эфире.
Ах да, чуть не забыли! Дарим промокод
→ Стать AI-инженером
🥱6🌚1
⚡️ Вы кешируете запросы в Redis, но забыли про OPcache?
PHP компилирует каждый
Минимальный конфиг для прода:
Почему validate\_timestamps=0 в проде?
При каждом запросе PHP проверяет mtime файла на диске. На высоких RPS — это сотни лишних stat()-syscall'ов в секунду. Инвалидируйте кеш вручную через opcache_reset() или перезапуск PHP-FPM при деплое.
💡 Хотите проверить, что лежит в кеше и сколько памяти занято? Используйте
Библиотека пхпшника
#vardump
PHP компилирует каждый
.php-файл в байткод при каждом запросе — если не настроен OPcache. Это означает лишние CPU-циклы на парсинг даже самого тривиального хелпера.Минимальный конфиг для прода:
; включаем
opcache.enable=1
opcache.enable_cli=1
; кол-во кешируемых файлов (>= числа файлов в проекте)
opcache.max_accelerated_files=20000
; размер разделяемой памяти (MB)
opcache.memory_consumption=256
; кешируем строки — экономим RAM
opcache.interned_strings_buffer=16
; в продакшне: 0 (не проверять изменения файлов)
opcache.validate_timestamps=0
Почему validate\_timestamps=0 в проде?
При каждом запросе PHP проверяет mtime файла на диске. На высоких RPS — это сотни лишних stat()-syscall'ов в секунду. Инвалидируйте кеш вручную через opcache_reset() или перезапуск PHP-FPM при деплое.
opcache_get_status() — или поставьте opcache-gui для визуального мониторинга.Библиотека пхпшника
#vardump
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥1
Forwarded from Библиотека задач по PHP | тесты, код, задания
🥱6👍2🔥1🤔1
Два инструмента, которые делают похожие вещи, но не одинаковые — и разница не стилистическая.
— switch использует нестрогое сравнение (==)
— match использует строгое (===) и является выражением
Вот классический баг, который живёт в каждом втором легаси-проекте:
$status = "0";
switch ($status) {
case 0: // "0" == 0 → true. Вот и приехали.
handleInactive();
break;
case "active":
handleActive();
break;
}
match решает это без магии:
$label = match($code) {
200, 201 => 'success',
301, 302 => 'redirect',
404 => 'not_found',
default => 'unknown',
};Несколько значений на один arm можно указать через запятую. Результат — значение, не сайд-эффект. Можно прямо в return или аргумент функции.
Про UnhandledMatchError: match без default бросает исключение, если значение не попало ни в один arm. switch молча пропускает. Это не недостаток match — это контракт. Явный фейл лучше тихого игнорирования.
🔹 Когда всё-таки switch:
— нужен fallthrough осознанно
— легаси на PHP 7
— в arm несколько выражений подряд, а не одно возвращаемое значение
Выбор инструмента — это не про стиль. Это про то, какие гарантии тебе нужны от кода.
#элементарный_выбор
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥2
У «Библиотеки программиста» появился резервный канал в мессенджере MAX
Он нужен исключительно для связи с теми, кто не может следить за обновлениями здесь из-за трудностей с доступом. Поэтому, если вы видите это сообщение, распространите его среди жильцов вашего ЖЭКа.
Контент в MAX будет дублировать телеграмный — основной нашей площадкой был и остаётся Telegram. Надеемся, это временная мера.
→ Подписаться на «Библиотеку программиста» в MAX
Он нужен исключительно для связи с теми, кто не может следить за обновлениями здесь из-за трудностей с доступом. Поэтому, если вы видите это сообщение, распространите его среди жильцов вашего ЖЭКа.
Контент в MAX будет дублировать телеграмный — основной нашей площадкой был и остаётся Telegram. Надеемся, это временная мера.
→ Подписаться на «Библиотеку программиста» в MAX
🥱18😁5😢3👾3
Кажется, мы окончательно перешли от игрушек к суровому AgentOps
Приглашаем на наш обновлённый курс по разработке ИИ-агентов. Никакой воды про «будущее нейросетей», только инженерный подход.
На курсе мы:
— пошагово строим готовые системы на
— настраиваем кэширование и роутинг, чтобы бот не сожрал токены;
— разбираемся со стейтом, учимся дебажить через time-travel и прикручиваем human-in-the-loop;
— выводим RAG в прод так, чтобы безопасники не завернули архитектуру из-за 152-ФЗ.
В пекло скучные лекции про общую инфраструктуру — сразу фокусируемся на агентных фреймворках и написании кода. Занятия ведут бывалые лиды из Газпромбанка и Альфы, набившие шишки на реальных задачах.
Сегодня последний день, когда можно забрать курс по старым ценам. Базовый тариф сейчас стоит 49 000 ₽ (вместо 62 990 ₽), продвинутый трек — 99 000 ₽ (вместо 124 990 ₽). Если не хочется отдавать всю сумму сразу, есть рассрочка. Торопитесь — на потоке осталось всего 5 мест!
→ Зафиксировать цену и перейти к сборке своих агентов
Приглашаем на наш обновлённый курс по разработке ИИ-агентов. Никакой воды про «будущее нейросетей», только инженерный подход.
На курсе мы:
— пошагово строим готовые системы на
LangGraph, CrewAI и MCP;— настраиваем кэширование и роутинг, чтобы бот не сожрал токены;
— разбираемся со стейтом, учимся дебажить через time-travel и прикручиваем human-in-the-loop;
— выводим RAG в прод так, чтобы безопасники не завернули архитектуру из-за 152-ФЗ.
В пекло скучные лекции про общую инфраструктуру — сразу фокусируемся на агентных фреймворках и написании кода. Занятия ведут бывалые лиды из Газпромбанка и Альфы, набившие шишки на реальных задачах.
Кстати, на днях мы пилили агента в прямом эфире, если пропустили — есть запись вебинара.
Сегодня последний день, когда можно забрать курс по старым ценам. Базовый тариф сейчас стоит 49 000 ₽ (вместо 62 990 ₽), продвинутый трек — 99 000 ₽ (вместо 124 990 ₽). Если не хочется отдавать всю сумму сразу, есть рассрочка. Торопитесь — на потоке осталось всего 5 мест!
→ Зафиксировать цену и перейти к сборке своих агентов
Forwarded from Библиотека собеса по PHP | вопросы с собеседований
yield превращает функцию в генератор. Вместо того чтобы собрать все данные в массив и вернуть целиком, функция отдаёт значения по одному, по мере запроса.
Главный профит — память. Если обрабатываешь CSV на 500 тысяч строк, с массивом ты загрузишь всё в RAM разом. С генератором в памяти живёт одна строка. Генератор реализует интерфейс Iterator, с ним работает foreach. Минус — нельзя перемотать назад, обойти можно только один раз. Используй когда данных много, порядок линейный, и случайный доступ не нужен.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥3
⌨️ Топ-вакансий по PHP за неделю
PHP разработчик (Symfony, Rest API) — от 100 000 до 150 000 ₽ — удалёнка
Middle PHP разработчик — от 150 000 до 250 000 ₽ — гибрид/удалёнка (Воронеж)
Team Lead (PHP, Laravel) — от 500 000 ₽ — удалёнка/гибрид (Москва)
➡️ Еще больше топовых вакансий — в нашем канале PHP Jobs
PHP разработчик (Symfony, Rest API) — от 100 000 до 150 000 ₽ — удалёнка
Middle PHP разработчик — от 150 000 до 250 000 ₽ — гибрид/удалёнка (Воронеж)
Team Lead (PHP, Laravel) — от 500 000 ₽ — удалёнка/гибрид (Москва)
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2❤1🔥1
Это профилировщик, написанный на PHP, который считывает информацию о запуске виртуальной машины PHP извне процесса.
Вы можете обнаружить узкие места производительности или утечки памяти в своих скриптах, не меняя целевой скрипт и не загружая расширения.
🔗 Github
#инструменты
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥3❤1
🐘 PHP для начинающих (и напоминание для опытных)
🔹 Query Scopes
Смотришь на свой код и замечаешь одно и то же в пяти местах:
Это не переиспользование кода. Это его копирование. Разница важная.
▪️ Local Scope — прячем логику в модель
Теперь вместо цепочки условий — читаемый вызов
▪️ Scope с параметром
Иногда нужна гибкость. Scope принимает аргументы:
▪️ Global Scope — когда условие должно быть всегда
Если SoftDeletes работает по всему приложению — это глобальный скоуп под капотом. Можно написать свой:
Теперь все запросы к этой модели автоматически фильтруются по тенанту. Без единого where в контроллерах.
Библиотека пхпшника
#php_азбука
🔹 Query Scopes
Смотришь на свой код и замечаешь одно и то же в пяти местах:
->where('status', 'active')->where('deleted_at', null)
->where('status', 'active')->where('deleted_at', null)
->where('status', 'active')->where('deleted_at', null)Это не переиспользование кода. Это его копирование. Разница важная.
▪️ Local Scope — прячем логику в модель
// User.php
public function scopeActive(Builder $query): Builder
{
return $query->where('status', 'active')
->whereNull('deleted_at');
}
public function scopeVerified(Builder $query): Builder
{
return $query->whereNotNull('email_verified_at');
}
Теперь вместо цепочки условий — читаемый вызов
// Было
User::where('status', 'active')
->whereNull('deleted_at')
->whereNotNull('email_verified_at')
->get();
// Стало
User::active()->verified()->get();
▪️ Scope с параметром
Иногда нужна гибкость. Scope принимает аргументы:
public function scopeOlderThan(Builder $query, int $days): Builder
{
return $query->where('created_at', '<', now()->subDays($days));
}
phpUser::active()->olderThan(30)->get();
▪️ Global Scope — когда условие должно быть всегда
Если SoftDeletes работает по всему приложению — это глобальный скоуп под капотом. Можно написать свой:
// В модели
protected static function booted(): void
{
static::addGlobalScope('tenant', function (Builder $builder) {
$builder->where('tenant_id', auth()->user()?->tenant_id);
});
}
Теперь все запросы к этой модели автоматически фильтруются по тенанту. Без единого where в контроллерах.
Библиотека пхпшника
#php_азбука
👍8❤4🔥2🥱1
⚙️ Laravel Process Pipe
С версии Laravel 10.7 появилась нативная поддержка конвейера процессов (pipe). Теперь можно легко передавать вывод одного процесса на вход другого — прямо из PHP-кода, без костылей.
Это аналог привычного cat example.txt | grep -i "laravel" в терминале, только внутри Laravel.
Зачем это нужно?
— Обработка файлов и потоков данных без временных переменных
— Чистый и читаемый код вместо вызовов shell_exec
— Удобное тестирование через фейковые процессы
Маленькая фича, но приятная 🙂
Библиотека пхпшника
#vardump
С версии Laravel 10.7 появилась нативная поддержка конвейера процессов (pipe). Теперь можно легко передавать вывод одного процесса на вход другого — прямо из PHP-кода, без костылей.
use Illuminate\Process\Pipe;
use Illuminate\Support\Facades\Process;
$result = Process::pipe(function (Pipe $pipe) {
$pipe->command('cat example.txt'),
$pipe->command('grep -i "laravel"'),
});
if ($result->successful()) {
// ...
}
Это аналог привычного cat example.txt | grep -i "laravel" в терминале, только внутри Laravel.
Зачем это нужно?
— Обработка файлов и потоков данных без временных переменных
— Чистый и читаемый код вместо вызовов shell_exec
— Удобное тестирование через фейковые процессы
Маленькая фича, но приятная 🙂
Библиотека пхпшника
#vardump
👍3❤2😁1
Почитали тут свежий отчёт по рынку ИИ-ускорителей в РФ: оказывается, 54% компаний тормозят внедрение ИИ исключительно из-за конских цен на инфраструктуру.
Ну, то есть написать пет-проект с вызовом API это задача на вечер, а вот запустить агента в продакшн так, чтобы он не сжёг бюджет отдела за неделю — суровая инженерия.
По сути, сейчас мало уметь собирать RAG. Нужно считать токены, настраивать
Также в программе:
— оценка качества, трейсинг и защита от деградации пайплайнов;
— мультиагентные паттерны и интеграция по протоколу
— локальный деплой Open Source под 152-ФЗ (когда данные нельзя выносить наружу).
Кажется, это единственный адекватный roadmap по переходу от блокнотов к enterprise-решениям.
Прямо сейчас можно урвать курс с увесистой скидкой(49 000 ₽ 62 990 ₽ за базовый тариф и 99 000 ₽ 124 990 ₽ за продвинутый трек) , но стоит поторопиться — на потоке осталось всего 5 мест.
👉 Зафиксировать цену и начать собирать агентов, за которых не стыдно в проде
Ну, то есть написать пет-проект с вызовом API это задача на вечер, а вот запустить агента в продакшн так, чтобы он не сжёг бюджет отдела за неделю — суровая инженерия.
По сути, сейчас мало уметь собирать RAG. Нужно считать токены, настраивать
time-travel дебаг в LangGraph и уметь роутить запросы на лету. Всё это мы учли в обновлённом курсе по разработке AI-агентов, где акцент сделан именно на AgentOps и жёсткий контроль ресурсов.Также в программе:
— оценка качества, трейсинг и защита от деградации пайплайнов;
— мультиагентные паттерны и интеграция по протоколу
MCP;— локальный деплой Open Source под 152-ФЗ (когда данные нельзя выносить наружу).
Кажется, это единственный адекватный roadmap по переходу от блокнотов к enterprise-решениям.
Прямо сейчас можно урвать курс с увесистой скидкой
👉 Зафиксировать цену и начать собирать агентов, за которых не стыдно в проде
🥱2