Unit of Work - узгоджені зміни
Групує кілька змін у єдину транзакцію - усе або нічого. У Laravel роль виконує DB::transaction() з автокомітом, ролбеком і повтором при deadlock.
Почніть вводити, щоб шукати по статтях, вакансіях, компаніях, проєктах, ресурсах, пакетах, подіях і користувачах.
Статті, новини, туторіали та переклади від учасників спільноти
Групує кілька змін у єдину транзакцію - усе або нічого. У Laravel роль виконує DB::transaction() з автокомітом, ролбеком і повтором при deadlock.
Потрібно подивитися стан колекції в середині ланцюга?
tap() дозволяє "підглянути" в колекцію, не змінюючи її.
Як працює:
Callback отримує колекцію, але повернуте значення ігнорується.
Сценарії:
Різниця з pipe():
$result = $users
->where('active', true)
->tap(fn($c) => logger("Active: {$c->count()}"))
->where('role', 'admin')
->tap(fn($c) => logger("Admins: {$c->count()}"))
->get();
// Порівняння
$collection->pipe(fn($c) => $c->count()); // повертає число
$collection->tap(fn($c) => $c->count()); // повертає колекцію
Потрібно застосувати складну логіку до всієї колекції?
pipe() передає в callback усю колекцію і повертає те, що callback повернув.
Переваги:
Різниця з map():
Порада: використовувати іменовані функції для читабельності.
$result = $users
->where('active', true)
->pipe(fn($c) => $c->sortBy('last_login')->take(10))
->values();
// Умовне сортування
$posts = Post::all()->pipe(function ($posts) use ($request) {
return $request->sort === 'popular'
? $posts->sortByDesc('views')
: $posts->sortByDesc('created_at');
});
// Дебаг
$result = $users
->where('active', true)
->pipe(fn($c) => tap($c, fn($c) => logger($c->count())))
->where('role', 'admin');
Зберігає не поточний стан, а послідовність подій, що його змінювали. Повний аудит і відтворюваність - ціною складнішої інфраструктури.
Команда Swoole відкрила вихідний код TypePHP - AOT-компілятора, що перетворює PHP-код у нативний машинний код через C++. Проєкт випущено раніше запланованого терміну й повністю написаний на PHP, включаючи самокомпіляцію.
Потрібно поділити користувачів на активних і неактивних?
partition() повертає одразу дві групи.
Різниця з filter():
Сценарії:
Порада: зручно для різних обробок двох груп.
[$active, $inactive] = $users->partition(fn($u) => $u->active);
// Дві різні обробки
$active->each(fn($u) => ...);
$inactive->each(fn($u) => ...);
// Валідація
[$valid, $invalid] = $orders->partition(fn($o) =>
$o->total > 0 && $o->email !== null
);
// Студенти
[$passed, $failed] = $students->partition(
fn($s) => $s->score >= 60
);
Розділяє операції зміни стану (команди) та читання (запити) на окремі моделі. Коли це виправдано у великих доменах і чому надмірне для CRUD.
Потрібно показати пости за категоріями? Вкладені цикли не потрібні.
groupBy() групує колекцію за ключем.
Як працює:
Повертає масив груп, де кожна група - окрема колекція.
Розширені можливості:
Порада: ідеально для аналітики, звітів і категоризації.
// Групування за категорією
$byCategory = $posts->groupBy('category_id');
// Групування за роком
$byYear = $posts->groupBy(fn($p) => $p->created_at->year);
// Доступ до груп
foreach ($byCategory as $categoryId => $posts) {
echo "Category {$categoryId}: {$posts->count()} posts\n";
}
// Кілька рівнів
$byYearMonth = $posts->groupBy([
fn($p) => $p->created_at->year,
fn($p) => $p->created_at->month,
]);
// Групування по зв'язку
$byPostTitle = $comments->groupBy('post.title');
// Практичний приклад - суми продажів
$report = $orders->groupBy('status')
->map(fn($group) => $group->sum('total'));
Потрібно прибрати частину елементів? Писати складні if не обов'язково.
filter() залишає елементи, що відповідають умові.
reject() прибирає елементи, що відповідають умові.
Різниця:
Розширено:
Для простих порівнянь краще where(), whereIn(), whereBetween().
Порада: filter() без callback прибирає всі falsy (null, false, 0, '', []).
// filter() - тільки активні
$active = $users->filter(fn($u) => $u->active === true);
// reject() - видалити неактивних
$active = $users->reject(fn($u) => $u->active === false);
// filter() без callback
$values = collect([1, 2, null, 3, false, '', 4]);
$cleaned = $values->filter();
// [1, 2, 3, 4]
// where()
$admins = $users->where('role', 'admin');
$verified = $users->where('email_verified_at', '!=', null);
// whereIn()
$staff = $users->whereIn('role', ['admin', 'moderator']);
// whereBetween()
$recent = $posts->whereBetween('created_at', [
now()->subDays(7),
now()
]);
// Комбінування фільтрів
$result = $users
->where('active', true)
->whereIn('role', ['admin', 'editor'])
->filter(fn($u) => $u->posts_count > 10);
Матеріали за темою «PHP»: усе, що ми писали про це українською. Нижче - суміжні теми, якщо шукаєте ширше.
Зараз опубліковано 139 матеріалів від 3 авторів. Останній матеріал - 30 жовтня 2026.