Eloquent ORM: модели и базовые запросы
Eloquent — это ORM Laravel, который превращает строки таблиц в PHP-объекты, позволяя работать с базой без единой строки SQL.
Суть: каждой таблице соответствует класс-модель. Через методы вроде
User::all(),User::find(1),User::where(...)вы достаёте и сохраняете данные как обычные объекты.
Писать SQL вручную утомительно и опасно: легко ошибиться в синтаксисе или открыть дыру для инъекций. Eloquent (это ORM — Object-Relational Mapping) убирает эту боль. Он связывает таблицу базы с PHP-классом: таблица products — это модель Product, каждая строка — экземпляр объекта, каждая колонка — свойство. Вы работаете с данными как с обычными объектами, а Eloquent сам генерирует безопасный SQL.
Eloquent опирается на соглашения. Модель Product по умолчанию работает с таблицей products (множественное число, нижний регистр). Первичный ключ — id. Поля created_at и updated_at ведутся автоматически. Если следовать этим правилам, код становится минимальным.
Создание модели и запросы
# создать модель (с миграцией через -m)
php artisan make:model Product -m<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
// какие поля можно массово заполнять
protected $fillable = ['name', 'price', 'is_active'];
// приведение типов (Laravel 11 — метод casts)
protected function casts(): array
{
return [
'is_active' => 'boolean',
'price' => 'decimal:2',
];
}
}<?php
// чтение
$all = Product::all(); // все товары
$one = Product::find(1); // по первичному ключу
$first = Product::where('is_active', true)->first();
$cheap = Product::where('price', '<', 1000)->get();
// создание
$product = Product::create([
'name' => 'Клавиатура',
'price' => 2500,
]);
// обновление
$product->price = 2300;
$product->save();
// удаление
$product->delete();Как работает под капотом
Каждый метод Eloquent под капотом строит SQL. Product::find(1) превращается в SELECT * FROM products WHERE id = 1 LIMIT 1, а результат «оборачивается» в объект модели. Цепочка where()->get() накапливает условия и выполняет запрос только при вызове get(). Параметры всегда передаются через подготовленные выражения — поэтому SQL-инъекции невозможны.
PHP-код Eloquent -> SQL под капотом
---------------- --------------
Product::all() -> SELECT * FROM products
Product::find(1) -> ... WHERE id = 1 LIMIT 1
->where('price','<',1000)->get() -> ... WHERE price < 1000
->create([...]) -> INSERT INTO products ...
$m->delete() -> DELETE FROM products WHERE id=?
Смоделируем фильтрацию коллекции (аналог where()->get()) на Python — Eloquent под капотом делает то же самое, но в базе.
Попробуй сам ▶
# Аналог Product::where('price','<',1000)->get()
products = [
{'name': 'Мышь', 'price': 800, 'active': True},
{'name': 'Клавиатура', 'price': 2500, 'active': True},
{'name': 'Коврик', 'price': 400, 'active': False},
]
def where(items, key, op, value):
ops = {'<': lambda a, b: a < b, '=': lambda a, b: a == b}
return [x for x in items if ops[op](x[key], value)]
cheap = where(products, 'price', '<', 1000)
for p in cheap:
print(p['name'], '-', p['price'])
Частые ошибки
- Забыть
$fillable. Без негоcreate()бросит ошибку защиты от массового присвоения. - Путать
get()иfirst().get()возвращает коллекцию,first()— одну модель (или null). - Сырой SQL без нужды. Конкатенация строк в запрос открывает SQL-инъекцию; пользуйтесь методами Eloquent.
Best practices
- Описывайте приведение типов через метод
casts()(новый стиль Laravel 11). - Используйте
findOrFail(), чтобы автоматически отдавать 404 для несуществующих записей. - Не вытаскивайте лишнего: для больших таблиц применяйте
paginate()и выборку нужных колонок.
Итог: Eloquent превращает работу с базой в работу с объектами и сам пишет безопасный SQL. Дальше разберём, как Eloquent связывает таблицы между собой через отношения.