Flyweight - спільні легкі об'єкти
Економить пам'ять, повторно використовуючи спільні екземпляри замість тисяч однакових. Розділення стану на внутрішній і зовнішній на прикладі кешу довідників.
Почніть вводити, щоб шукати по статтях, вакансіях, компаніях, проєктах, ресурсах, пакетах, подіях і користувачах.
Статті, новини, туторіали та переклади від учасників спільноти
Економить пам'ять, повторно використовуючи спільні екземпляри замість тисяч однакових. Розділення стану на внутрішній і зовнішній на прикладі кешу довідників.
Потрібні обчислені колонки без завантаження повних моделей?
selectRaw() робить обчислення на рівні SQL.
База даних обробляє. Повертає тільки результати.
Поширене використання:
Виграш продуктивності:
База даних робить математику. Не PHP. Повертає тільки те що потрібно.
Порада: Завжди використовувати parameter binding щоб запобігти SQL ін'єкції.
У десятому епізоді серії Ship AI with Laravel показано, як тестувати повноцінну AI-платформу за допомогою Pest без витрат на API-виклики. Використовуючи систему фейків SDK, можна перевіряти агентів, інструменти, векторні бази знань та чат-потоки з детермінованими результатами.
cursor() тримає з'єднання з БД відкритим. Ризиковано для довгих операцій.
lazy() використовує chunks внутрішньо. Безпечніше.
Як працює lazy():
Завантажує дані пакетами (типово 1000). Видає елементи один за одним. Закриває з'єднання між пакетами.
Продуктивність:
Ефективна пам'ять як cursor(). Безпека з'єднання як chunk(). Найкраще з обох світів.
Порада: Налаштуй розмір chunk з lazy(500) для точного налаштування.
// Ризиковано: З'єднання залишається відкритим
User::cursor()->each(function ($user) {
// Довга обробка тут може таймаутнути
$this->sendEmail($user);
});
// Краще: Chunks з lazy ітерацією
User::lazy()->each(function ($user) {
// Безпечніше для довгих операцій
$this->sendEmail($user);
});
// Власний розмір chunk
User::lazy(200)->each(function ($user) {
$this->processUser($user);
});
// Працює з фільтрами
User::where('active', true)
->orderBy('created_at')
->lazy()
->filter(fn($user) => $user->hasOrders())
->each(fn($user) => $this->sendPromo($user));
Новий пакет Laravel WhatsApp від Md Mostafijur Rahman дозволяє надсилати та отримувати повідомлення WhatsApp через офіційний Cloud API Meta та неофіційний веб-інтерфейс за допомогою whatsapp-web.js. Обидва варіанти працюють через єдиний фасад WhatsApp::.
Потрібна сира продуктивність? Eloquent моделі додають накладні витрати.
toBase() конвертує запит в базовий query builder. Без гідратації моделі.
Повертає stdClass замість моделей. Швидше. Менше пам'яті.
Коли використовувати:
Компроміс:
Немає accessors, mutators або зв'язків. Тільки сирі дані.
Порада: Використовувати для операцій тільки читання на великих наборах даних.
// ПОГАНО: Створює 10,000 Eloquent моделей
$users = User::where('active', true)->get();
// ДОБРЕ: Повертає stdClass об'єкти
$users = User::where('active', true)
->toBase()
->get();
// Приклад: Експорт в CSV
$users = User::select('name', 'email')
->toBase()
->get();
foreach ($users as $user) {
// $user це stdClass, не User модель
fputcsv($file, [$user->name, $user->email]);
}
// Працює з chunk теж
User::where('active', true)
->toBase()
->chunk(1000, function($users) {
// Обробка без накладних витрат моделі
});
Надає простий інтерфейс до складної підсистеми. Як фасади Laravel ховають контейнер за коротким викликом і де межа, за якою фасад стає God Object.
Побудова фільтрів пошуку з купою if виразів? Код стає нечитабельним.
Dynamic scopes дозволяють чисто ланцюжити умови.
Патерн:
Кожен scope повертає query builder. Ланцюжи декількох scopes разом.
Просунута техніка:
Використовувати when() всередині scopes для опціональних умов.
Переваги:
Порада: Створи базовий scope на якому можуть будуватися інші scopes.
// Модель User
public function scopeFilter($query, array $filters)
{
return $query
->when($filters['status'] ?? false,
fn($q, $status) => $q->where('status', $status))
->when($filters['role'] ?? false,
fn($q, $role) => $q->where('role', $role))
->when($filters['search'] ?? false,
fn($q, $search) => $q->where('name', 'like', "%{$search}%"))
->when($filters['date_from'] ?? false,
fn($q, $date) => $q->whereDate('created_at', '>=', $date))
->when($filters['date_to'] ?? false,
fn($q, $date) => $q->whereDate('created_at', '<=', $date));
}
// Контролер - чисто і просто
public function index(Request $request)
{
return User::filter($request->only([
'status', 'role', 'search', 'date_from', 'date_to'
]))->paginate();
}
Потрібен складний SQL? Функції дат? Математичні операції?
Eloquent має межі. DB::raw() дозволяє писати сирий SQL всередині запитів.
Поширені випадки використання:
Попередження безпеки:
Ніколи не передавай вхідні дані користувача безпосередньо в raw(). Використовувати біндінги.
Порада: Розглянь власні query scopes щоб повторно використовувати складні raw вирази.
// Функції дат
$users = User::where('created_at', '>=',
DB::raw('DATE_SUB(NOW(), INTERVAL 30 DAY)')
)->get();
// Математичні операції
$products = Product::select('*',
DB::raw('price * quantity as total')
)->get();
// CASE вирази
$posts = Post::select('*',
DB::raw('CASE WHEN views > 1000 THEN "popular"
ELSE "regular" END as status')
)->get();
// Агрегація з групуванням
$stats = Order::select(
DB::raw('DATE(created_at) as date'),
DB::raw('SUM(total) as revenue'),
DB::raw('COUNT(*) as orders')
)
->groupBy('date')
->get();
// БЕЗПЕЧНО: Використання біндінгів
$status = 'published';
Post::whereRaw('LOWER(status) = ?', [strtolower($status)])->get();
Матеріали за темою «Laravel»: усе, що ми писали про це українською. Нижче - суміжні теми, якщо шукаєте ширше.
Зараз опубліковано 150 матеріалів від 3 авторів. Останній матеріал - 12 вересня 2026.