Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
Tips 01 липня 2026

selectRaw() для обчислюваних колонок

Потрібні обчислені колонки без завантаження повних моделей?

selectRaw() робить обчислення на рівні SQL. База даних обробляє. Повертає тільки результати.

Поширене використання:

  • Ціна з податком
  • Вік з дати народження
  • Обчислення відстані
  • Об'єднані рядки

Виграш продуктивності:

База даних робить математику. Не PHP. Повертає тільки те що потрібно.

Порада: Завжди використовувати parameter binding щоб запобігти SQL ін'єкції.

// Обчислення на стороні бази даних
$products = Product::selectRaw('
    id,
    name,
    price,
    price * 1.2 as price_with_tax,
    price * quantity as total
')->get();

// Обчислення віку
$users = User::selectRaw('
    id,
    name,
    YEAR(CURDATE()) - YEAR(birthdate) as age
')->get();

// Конкатенація
$users = User::selectRaw("
    CONCAT(first_name, ' ', last_name) as full_name,
    email
")->get();

// Безпечний parameter binding
$taxRate = 1.15;
$products = Product::selectRaw(
    'price * ? as price_with_tax',
    [$taxRate]
)->get();
// Обчислення відстані
$lat = 40.7128;
$lng = -74.0060;

$stores = Store::selectRaw("
    *,
    (6371 * acos(cos(radians(?))
    * cos(radians(lat))
    * cos(radians(lng) - radians(?))
    + sin(radians(?))
    * sin(radians(lat)))) AS distance
", [$lat, $lng, $lat])
    ->having('distance', '<', 10)
    ->orderBy('distance')
    ->get();

// Складні обчислення з декількома параметрами
$discount = 0.1;
$minPrice = 100;

$items = Product::selectRaw('
    id,
    name,
    price,
    price * (1 - ?) as discounted_price,
    CASE WHEN price > ? THEN "premium" ELSE "standard" END as tier
', [$discount, $minPrice])->get();

Читати в документації

Коментарі

Увійдіть, щоб залишити коментар

Будьте першим, хто залишить коментар!

Інші поради

Tips 16 жовтня 2026

`confirmed` - підтвердження пароля без ручних порівнянь

Робите підтвердження пароля й порівнюєте поля вручну?

confirmed робить це автоматично.

Як працює:

Перевіряє, що поле збігається з {field}_confirmation.

Для password автоматично очікує password_confirmation.

Конвенція:

  • Поле: password
  • Підтвердження: password_confirmation

Працює з:

будь-якими полями — пароль, email тощо.

Порада: поле _confirmation не потрібно валідувати окремо.

public function rules()
{
  return [
    'password' => 'required|confirmed|min:8',
    'email' => 'required|email|confirmed',
    'new_password' => 'required|confirmed|min:8',
  ];
}
Tips 14 жовтня 2026

`prohibits` - взаємовиключна валідація

Користувач може платити карткою АБО PayPal. Не обома.

Писати кастомну логіку? Є вбудоване правило.

prohibits гарантує, що поле не може бути присутнім разом з іншим.

Коли корисно:

  • Взаємовиключні способи оплати
  • Або email, або телефон
  • Умовні обмеження полів

Схожі правила:

  • required_without — потрібно A, якщо B немає
  • required_with — потрібно A, якщо B є
  • prohibits — A забороняє B

Порада: комбінуйте з required_without для сценарію “або A, або B, але не обидва”.

public function rules()
{
  return [
    'card_number' => 'prohibits:paypal_email',
    'paypal_email' => 'prohibits:card_number',

    'email' => 'required_without:username|prohibits:username',
    'username' => 'required_without:email|prohibits:email',
  ];
}
Tips 12 жовтня 2026

`bail` - зупинити валідацію після першої помилки

У поля email 5 правил. Усі падають — користувач бачить 5 помилок.

Це плутає.

bail зупиняє валідацію поля на першій помилці.

Навіщо:

  • Кращий UX — по одній помилці
  • Продуктивність — не запускаємо дорогі перевірки
  • Чіткіші повідомлення

Як працює:

Додайте bail першим правилом для поля.

Порада: ставте перед дорогими правилами типу exists:, unique: або кастомними перевірками з API.

public function rules()
{
  return [
    'email' => 'bail|required|email|max:255|unique:users',
    'username' => [
      'bail',
      'required',
      'min:3',
      Rule::unique('users')->ignore($this->user),
      new CheckExternalAPI,
    ],
  ];
}
Tips 09 жовтня 2026

`prepareForValidation()` - чистимо дані до валідації

Телефон приходить як "(123) 456-7890", а в БД потрібен "1234567890".

Санітизація в контролері? Це вже запізно.

prepareForValidation() змінює дані запиту до запуску правил.

Коли корисно:

  • Нормалізація телефону
  • Прибирання пробілів
  • Конвертація типів
  • Додавання обчислюваних полів

Важливо:

Виконується до валідації — ідеально для нормалізації.

Порада: merge() додає/оновлює поля, replace() повністю замінює масив даних.

protected function prepareForValidation()
{
  $this->merge([
    'phone' => preg_replace('/[^0-9]/', '', $this->phone),
    'slug' => Str::slug($this->title),
    'price' => (float) $this->price,
    'name' => trim($this->name),
    'email' => strtolower(trim($this->email)),
  ]);
}
Tips 07 жовтня 2026

`exclude()` - прибираємо поля з валідованих даних

У формі є CSRF-токен та допоміжні поля. Ви не хочете, щоб вони потрапили у validated().

exclude_if, exclude_unless прибирають поля умовно.

Коли корисно:

  • Прибрати UI-only поля
  • Виключити поля залежно від ролі
  • Не логувати чутливі поля
  • Тримати валідовані дані “чистими”

Доступні правила:

  • exclude — завжди прибирає
  • exclude_if — прибирає, якщо умова істинна
  • exclude_unless — прибирає, якщо умова хибна
  • exclude_with — прибирає, якщо інше поле присутнє

Порада: краще за ручний unset() після валідації.

public function rules()
{
  return [
    'name' => 'required',
    'admin_notes' => 'exclude', // не потрапить у validated()
    'is_admin' => 'exclude_unless:user.role,admin',
    'card_number' => 'exclude_if:payment_method,cash',
    'paypal_email' => 'exclude_if:payment_method,card',
  ];
}
Завантаження...