Laravel — Database ed Eloquent ORM

Migration · Model · Query Builder · Relazioni · Laravel 11 · Marco Consiglio
Volta Institute · Napoli
A.A. 2026
🗺️ Cos'è Eloquent — parlare al database senza scrivere SQL
Nella guida PHP+MySQL PDO già vista, ogni interazione col database richiedeva scrivere manualmente query SQL (SELECT, INSERT) e prepared statement. Eloquent è l'ORM (Object-Relational Mapping) di Laravel: rappresenta ogni tabella del database come una CLASSE PHP, e ogni riga come un OGGETTO di quella classe — permettendo di scrivere Articolo::all() invece di SELECT * FROM articoli.
🎯 Da dove si parte: questa guida presuppone di aver completato Laravel Fondamenti (routing, controller, Blade) e di conoscere le basi di MySQL (guida MySQL Basi/CRUD). Non serve conoscenza pregressa di ORM.
⚙️ Configurare la connessione — il file .env
A differenza del PHP puro (dove config.php conteneva le credenziali direttamente, guida PHP+MySQL PDO), Laravel le tiene in un file .env separato, mai incluso nel controllo versione (Git).
# file .env, nella cartella principale del progetto DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=nome_database DB_USERNAME=root DB_PASSWORD=
⚠️ Il file .env contiene dati sensibili (password del database): non va MAI condiviso pubblicamente o caricato su repository Git pubblici — Laravel lo esclude automaticamente tramite .gitignore nella configurazione predefinita.
🏗️ Migration — creare tabelle scrivendo PHP invece di SQL
Una migration è un file PHP che descrive la struttura di una tabella (colonne, tipi) — invece di scrivere CREATE TABLE in SQL (guida MySQL Basi), si scrive PHP che Laravel traduce in SQL, ed è tracciabile nel tempo come un file di codice versionabile.
# genera un nuovo file migration vuoto php artisan make:migration create_articoli_table
// database/migrations/xxxx_create_articoli_table.php public function up(): void { Schema::create('articoli', function (Blueprint $table) { $table->id(); // colonna id, auto-incremento, chiave primaria $table->string('titolo'); $table->text('contenuto'); $table->timestamps(); // aggiunge created_at e updated_at automaticamente }); }
# esegue TUTTE le migration non ancora applicate, creando le tabelle nel database php artisan migrate
💡 $table->timestamps() aggiunge automaticamente due colonne (created_at, updated_at) gestite in automatico da Eloquent — equivalente concettuale della colonna creato_il TIMESTAMP scritta manualmente nelle guide PHP+MySQL precedenti, ma con AGGIORNAMENTO automatico incluso.
✅ Checkpoint: dopo php artisan migrate, verifica con un client MySQL che la tabella articoli sia stata effettivamente creata con le colonne definite.
📦 Model — la classe PHP che rappresenta una tabella
# genera un model, spesso insieme alla migration in un solo comando php artisan make:model Articolo -m
// app/Models/Articolo.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Articolo extends Model { // per default, Eloquent assume che il model 'Articolo' corrisponda // alla tabella 'articoli' (nome al plurale, minuscolo) }
⚠️ Questa convenzione (model Articolo singolare → tabella articoli plurale) è automatica: se il nome della tabella non segue questa regola, va specificato esplicitamente con protected $table = 'nome_tabella'; dentro la classe.
🔍 Query Builder — leggere e scrivere dati senza SQL
// recuperare TUTTI gli articoli (equivalente di SELECT * FROM articoli) $articoli = Articolo::all(); // recuperare UN articolo per id (equivalente di SELECT * FROM articoli WHERE id = ...) $articolo = Articolo::find(1); // filtrare con condizioni (equivalente di WHERE) $recenti = Articolo::where('creato_il', '>', '2026-01-01')->get(); // creare un nuovo record (equivalente di INSERT) Articolo::create([ 'titolo' => 'Il mio primo articolo', 'contenuto' => 'Testo di esempio.' ]); // aggiornare un record esistente (equivalente di UPDATE) $articolo = Articolo::find(1); $articolo->titolo = 'Titolo aggiornato'; $articolo->save(); // eliminare un record (equivalente di DELETE) Articolo::destroy(1);
💡 Ogni operazione CRUD (Create, Read, Update, Delete) già vista in SQL puro (guida MySQL Basi/CRUD) ha un metodo Eloquent diretto — la differenza è che Eloquent genera automaticamente la query SQL corretta e USA GIÀ i prepared statement internamente, proteggendo automaticamente da SQL injection senza scrivere bindValue() manualmente come nella guida PDO.
🔗 Relazioni — collegare model come si collegano le tabelle
Le guide sui progetti PHP+MySQL (CMS, Forum, ecc.) usavano JOIN in SQL per collegare tabelle correlate. Eloquent rappresenta le stesse relazioni direttamente nei model, con metodi dedicati.
// app/Models/Articolo.php — un articolo appartiene a UN autore public function autore() { return $this->belongsTo(Utente::class); } // app/Models/Utente.php — un utente può avere MOLTI articoli public function articoli() { return $this->hasMany(Articolo::class); }
// USO: accedere ai dati collegati come se fossero proprietà dell'oggetto $articolo = Articolo::find(1); echo $articolo->autore->nome; // Eloquent esegue automaticamente il JOIN necessario $utente = Utente::find(1); foreach ($utente->articoli as $art) { echo $art->titolo; }
✅ belongsTo/hasMany sono l'equivalente concettuale delle FOREIGN KEY e delle query INNER JOIN già viste nella guida MySQL Join/Relazioni — Eloquent genera automaticamente il JOIN corretto quando si accede a $articolo->autore, senza scrivere la query manualmente.
🧩 Applicazioni tipiche
TipologiaUso tipico
Blog/CMS con LaravelModel Articolo, Categoria, Commento con relazioni hasMany/belongsTo
E-commerceModel Prodotto, Ordine, Cliente con relazioni many-to-many (non trattate in questa guida introduttiva)
API RESTModel che restituiscono automaticamente JSON quando richiamati da un'app mobile o frontend JavaScript
🎓 Esercitazioni pratiche
1
Migration e model per una tabella "prodotti"
Crea una migration per una tabella prodotti (nome, prezzo, quantità), esegui php artisan migrate, poi crea il model Prodotto corrispondente.
⏱ 25 min📦 1 migration + 1 model💻 Individuale
2
CRUD completo con Query Builder
In un controller, scrivi metodi che usino Prodotto::create(), Prodotto::all(), un update tramite find()+save(), e Prodotto::destroy() per gestire il ciclo di vita completo di un prodotto.
⏱ 30 min📦 1 controller💻 Individuale
3
Relazione hasMany/belongsTo tra Categoria e Prodotto
Aggiungi una tabella categorie collegata a prodotti tramite categoria_id, definisci le relazioni nei rispettivi model, e verifica che $prodotto->categoria->nome funzioni correttamente.
⏱ 30 min📦 2 migration + 2 model💻 Individuale