Библиотека пхпшника | PHP, Laravel, Symfony, CodeIgniter
10.8K subscribers
1.62K photos
27 videos
26 files
4.39K links
Все самое полезное для пхпшника в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/bca892d6

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a5d13cd6fa92100ee6f68b
Download Telegram
💡 Используй array_filter() без колбэка

Не все знают, что array_filter() без второго аргумента убирает все «пустые» значения автоматически:
php
$data = [0, '', null, false, 'hello', 42, [], 'world'];

$result = array_filter($data);

// ['hello', 42, 'world']


Удалит: 0, '', null, false, []
Оставит: всё, что приводится к true

⚠️ Ловушка: ключи сохраняются! Если нужен чистый массив — добавь array_values().

Используй это для очистки данных формы или фильтрации результатов из БД перед обработкой.

Библиотека пхпшника

#vardump
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥1
Последний шанс: 3 курса по цене 1 и запуск AI-агентов в продакшн

Писать контроллеры на Laravel — привычно, но бизнесу нужна умная автоматизация. Как обогатить бэкенд мультиагентными системами, контролировать затраты на внешние API и работать по 152-ФЗ?

В обновлённой программе фокус смещён на инжиниринг и вывод ИИ-фич в прод. Вы изучите архитектуру ReAct-циклов, интеграцию оркестраторов вроде LangGraph, продвинутый RAG, стандарты MCP и AgentOps. Все ключевые навыки в одном месте: измеримость, time-travel дебаггинг, стабильная структурная генерация JSON, human-in-the-loop и интеграция агентов с легаси-системами.

Почему нельзя откладывать:

— масштабная акция «3 курса по цене 1» сгорит уже завтра;
— промокод Agent на скидку 10 000 рублей действует последние часы;
— сразу после оформления открываются материалы для подготовки — начать учиться можно прямо сейчас.

Забронировать место на курсе и забрать бонусы до 28 февраля
⚙️ Phiki

Phiki помогает подсветить синтаксис. Написан на PHP. Он использует файлы грамматики TextMate и темы Visual Studio Code для генерации кода с подсветкой синтаксиса для веба.

Название и публичный API Phiki во многом вдохновлены Shiki — пакетом, который делает примерно то же самое в экосистеме JavaScript. Реализация пакета также во многом вдохновлена vscode-textmate — мощным пакетом, лежащим в основе Visual Studio Code, Shiki и других инструментов.

🔗 Github

Библиотека пхпшника

#инструменты
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🎉2🔥1
Да, PHP умирает... уже 20 лет, а зарплаты всё растут. Но готов ли ты к роли кофаундера? 🚀

Пока эксперты хоронят стек, Proglib App строит будущее EdTech-платформы. Это экосистема с квизами, курсами и ИИ-тьюторами. MVP в проде, юзеры на борту, и проекту нужен технический лидер, готовый взять на себя архитектуру.

Это шанс выйти за рамки привычного бэкенда и стать партнёром в амбициозном продукте.

🛠️ Стек (без legacy-боли):

React 18, TypeScript, Vite, Express 5, PostgreSQL, Drizzle ORM.

Твои задачи:

• Проектировать масштабируемую архитектуру и пилить фичи. • Рефакторить, писать тесты и делать качественное код-ревью. • Работать автономно в связке с основателем.

Идеальный мэтч, если:

• Уверенно владеешь TS, React и Node.js (или готов быстро пересесть). • Используешь Claude Code и Cursor для ускорения разработки. • Бонус: опыт создания ИИ-агентов и интерес к обучению.

Удалёнка, гибкий график, отсутствие бюрократии.

Готов делать продукт, которым будут пользоваться тысячи коллег? Пиши о себе и кидай GitHub 👇
4😁4🥱1
💡 Используй array_map + array_filter с null колбэком для мультимерного flatten

Не городи рекурсию там, где достаточно одной строки через SPL или array_merge(...array_map(...)):
$matrix = [[1, 2, 3], [4, 5], [6]];

// Цикл или рекурсия
$result = [];
foreach ($matrix as $row) {
foreach ($row as $item) {
$result[] = $item;
}
}

// Одна строка
$result = array_merge(...$matrix);
// [1, 2, 3, 4, 5, 6]


Но вот где реальная магия — когда нужно flatten + filter за раз:
$data = [[1, 0, 2], [null, 3], [false, 4, '']];

$result = array_values(
array_filter(
array_merge(...$data)
)
);
// [1, 2, 3, 4]


⚠️ Ловушки

— array_merge(...$matrix) упадёт с ошибкой на пустом массиве [].
— Работает только для одного уровня вложенности.

📦 В продакшене это спасает при обработке сгруппированных результатов из БД, когда ORM отдаёт Collection[] и нужно быстро схлопнуть в плоский список.

Библиотека пхпшника

#vardump
Please open Telegram to view this post
VIEW IN TELEGRAM
👍62🔥1😁1🥱1
Как устроена типизация в PHP 8.x?

PHP долго был языком с динамической типизацией и репутацией «всё приведётся само». Начиная с PHP 7, а особенно с версий 8.0–8.3, система типов стала по-настоящему выразительной.

🔍 Что появилось и зачем

🔹 Union Types (8.0)

Тип может быть одним из нескольких:
function process(int|string $id): User|null {
// ...
}

Раньше это документировали только в PHPDoc и надеялись на лучшее.

🔹 mixed, never, void

▪️ mixed — явно говорит "любой тип", в отличие от отсутствия типа
▪️ never — функция никогда не вернёт управление (бросает исключение или завершает процесс)
▪️ void — функция ничего не возвращает

function redirect(string $url): never {
header("Location: $url");
exit();
}


🔹 Intersection Types (8.1)

Значение должно реализовывать все указанные интерфейсы одновременно:
function process(Serializable&Countable $data): void {
// ...
}

Полезно при работе с коллекциями и DTO, которые соответствуют нескольким контрактам.

🔹 Enums (8.1)


Наконец-то нативные перечисления вместо констант в классах:
enum Status: string {
case Active = 'active';
case Inactive = 'inactive';
}

function setStatus(Status $status): void { ... }

Теперь нельзя передать произвольную строку туда, где ожидается Status.

🔹 Readonly properties (8.1) и readonly классы (8.2)

class User {
public function __construct(
public readonly int $id,
public readonly string $name,
) {}
}

В 8.2 можно пометить весь класс как readonly — все свойства автоматически становятся иммутабельными. Отлично подходит для Value Objects и DTO.

🔹 DNF Types — Disjunctive Normal Form (8.2)

Комбинация union и intersection:
function handle(Countable&Iterator|null $collection): void {
// ...
}

Тип читается как: "реализует оба интерфейса, либо null".

🔹 typed class constants (8.3)

class Config {
const string VERSION = '1.0.0';
const int MAX_RETRIES = 3;
}

До 8.3 константы классов не имели типов — теперь контракт полный.

⚠️ Нюансы

— declare(strict_types=1) обязателен, иначе PHP будет тихо приводить типы и "5" пройдёт там, где ожидается int
— Intersection types не работают с примитивами только с интерфейсами и классами
— readonly нельзя применить к static свойствам
— Enums не поддерживают наследование

Библиотека пхпшника
Please open Telegram to view this post
VIEW IN TELEGRAM
👍83🔥2
Что такое Fibers в PHP 8.1 и чем они отличаются от async/await в других языках?

Fiber — примитив для кооперативной многозадачности. Позволяет приостановить выполнение функции в произвольной точке через Fiber::suspend() и возобновить позже, передав значение обратно.

Главное отличие от async/await: Fibers не заражают сигнатуры. В JS как только где-то await — вся цепочка выше должна быть async. В PHP Fiber::suspend() можно вызвать на любой глубине стека, не меняя сигнатуры вызывающих функций.

Второе отличие — Fibers это низкоуровневый примитив, event loop в них не встроен. Сами по себе они не дают параллелизма — это строительный блок, поверх которого ReactPHP, Revolt и Amp строят настоящую неблокирующую конкурентность.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍21
👀 А вы говорите «спасибо» ИИ?

Иногда пишу нейронке «спасибо» на случай, если через 10 появится Skynet, для поддержания базовой грамотности рабочего диалога.

А вы как? Благодарите после удачного ответа или общаетесь с ИИ как с микроволновкой?

💬 Делитесь опытом, может через пару лет эти комментарии станут вашим алиби

🐸 Библиотека пхпшника

#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8😁5🔥1
🔥 PDO vs MySQLi

Каждый рано или поздно задаёт себе вопрос:
«А почему мы вообще используем именно это?»


Чаще всего ответ → «так исторически сложилось». Но давай разберём более делательно.

🔹 MySQLi — быстрый, но привязанный

Работает только с MySQL/MariaDB. Зато даёт нативные async-запросы через mysqli_poll(), что редкость, но иногда критично.
$stmt = $mysqli->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $id);
$stmt->execute();


Синтаксис bind_param с типами — это боль при большом числе параметров.

🔹 PDO — абстракция с характером

Поддерживает 12+ драйверов: MySQL, PostgreSQL, SQLite, MSSQL, и др. Именованные плейсхолдеры — читаемость на уровне:
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id AND role = :role");
$stmt->execute(['id' => $id, 'role' => $role]);


Одна нотация везде. Смена БД без переписывания логики запросов.

📊 Что реально важно на проекте

Смена БД когда-либо → PDO (без вариантов)
Legacy MySQL-проект → MySQLi уже там, не трогай
Нужен fetchAll в объекты → PDO::FETCH_CLASS чище
Производительность → разница < 1%, забудь

💡 Вердикт

MySQLi — это не "плохо". Это инструмент под конкретный стек.

Но если ты стартуешь проект с нуля или пишешь библиотеку, то лучше PDO. Любой ORM (Doctrine, Eloquent) под капотом использует именно его.

🐸 Библиотека пхпшника

#элементарный_выбор
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥21😢1
⌨️ Топ-вакансий по PHP за неделю

PHP (Laravel) backend разработчик — от 80 000 до 130 000 ₽ — удалёнка

Middle Fullstack Developer (Laravel + Vue.js) (Contractor, Remote) — от 2500 до 3800 $ — удалёнка

Senior / Lead PHP (Symfony) Engineer — от 3000 до 7000 $ — удалёнка

➡️ Еще больше топовых вакансий — в нашем канале PHP Jobs
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1🔥1
🔧 Фишка PHP

match с true — замена громоздкому if-elseif

//  Было
if ($score >= 90) {
$grade = 'A';
} elseif ($score >= 75) {
$grade = 'B';
} elseif ($score >= 60) {
$grade = 'C';
} else {
$grade = 'F';
}

// Стало
$grade = match(true) {
$score >= 90 => 'A',
$score >= 75 => 'B',
$score >= 60 => 'C',
default => 'F',
};


Читается сверху вниз, возвращает значение, не требует break.

💡 match использует строгое сравнение (===), а при отсутствии default бросает UnhandledMatchError. Всегда добавляй default если входные данные непредсказуемы.

🐸 Библиотека пхпшника
Please open Telegram to view this post
VIEW IN TELEGRAM
👍193🔥3🥱3
This media is not supported in your browser
VIEW IN TELEGRAM
😁2🥱2
👍 На курсе по контролируемой разработке AI-агентов мы будем разбирать ровно то, о чём говорит Владислав в голосовом, но уже в формате системной практики.

📅 Старт курса — 20 апреля.

Если хотите разобраться, как строить управляемые агентные системы:
➡️ Присоединяйтесь.

P.S. С первого занятия будет практика: код и разбор реальных ошибок, а не только теория.
Please open Telegram to view this post
VIEW IN TELEGRAM
🐘 PHP для начинающих (и напоминание для опытных)

🔹 Eloquent Relationships или почему связи это не страшно

Большинство новичков понимают модели. Один класс — одна таблица, всё логично.

Страшно становится, когда таблицы нужно связывать между собой. В голове сразу всплывают JOIN-ы из курса по SQL, и хочется закрыть ноутбук.

Eloquent это скрывает. Ты просто описываешь словами, как модели связаны друг с другом.

// User.php
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}

// Post.php
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}


Всё. Laravel сам догадается, что posts.user_id ссылается на users.id — по соглашению об именовании. Теперь можно писать читаемый код:

// Все посты пользователя
$user->posts;

// Автор конкретного поста
$post->user->name;

// Посты только опубликованные
$user->posts()->where('published', true)->get();


Никаких JOIN-ов вручную. Никакого WHERE user_id = ?. Ты работаешь с объектами, а не с сырым SQL.

Три связи, которые покрывают 90% случаев

▪️ hasMany — у пользователя много постов
▪️ belongsTo — пост принадлежит пользователю
▪️ belongsToMany — пост имеет много тегов, тег стоит на многих постах (промежуточная таблица)

Связи — это просто способ сказать Laravel: «вот как мои таблицы соотносятся». Дальше он разберётся сам.

Библиотека пхпшника

#php_азбука
👍5🔥1
💡 Бесплатный таймер, который уже запущен

Не городи microtime(true) в начале index.php, когда PHP сделал это за тебя:
//  Часто вижу
define('APP_START', microtime(true));
// ... где-то в конце
$elapsed = microtime(true) - APP_START;

// Уже есть
$elapsed = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];


Разница принципиальная. APP_START фиксирует момент после автозагрузки, DI-контейнера и прочего bootstrap'а. REQUEST_TIME_FLOAT — реальный старт запроса на уровне PHP-FPM.

// Логируй реальное время ответа в footer или middleware
header('X-Response-Time: ' . round(
(microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']) * 1000, 2
) . 'ms');


⚠️ Ловушки

— В CLI REQUEST_TIME_FLOAT есть, но равен моменту запуска скрипта.
— Не путай с REQUEST_TIME (int, секунды) — для замеров он бесполезен.

Библиотека пхпшника

#vardump
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥43
🔥 Named arguments — удобство, которое ломает рефакторинг

// Переименовал параметр — и где-то тихо упало
function createUser(string $name, bool $isActive): void {}

createUser(name: 'Ivan', active: true); // Fatal


Имя параметра теперь публичный контракт. Rector, IDE-рефакторинг, переименование в наследнике — всё это теперь breaking change.

💬 А вы юзаете named arguments в публичном API или только внутри?

Библиотека пхпшника

#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
😁5👍1🔥1