Prologo
Primi Passi
Architettura
Le Basi
- Routing
- Middleware
- Protezione da CSRF
- Controller
- Richieste
- Risposte
- Views
- Blade
- Vite
- URL
- Sessioni
- Validazione
- Errori
- Logging
Approfondimenti
- Artisan
- Broadcasting
- Cache
- Collezioni
- Concorrenza
- Contesto
- Contratti
- Eventi
- File System
- Helpers
- Client HTTP
- Localizzazione
- Notifiche
- Sviluppo di Package
- Processi
- Code
- Rate-limiting
- Stringhe
- Scheduling di Task
Sicurezza
Database
Eloquent ORM
Testing
Package
Migrazioni
- Introduzione
- Generazione delle Migrazioni
- Struttura delle migration
- Eseguire le Migrazioni
- Tabelle
- Colonne
- Indici
- Eventi
Introduzione
Le migrazioni sono come il controllo delle versioni per il tuo database, permettendo al tuo team di definire e condividere la definizione dello schema del database dell’applicazione. Se hai mai dovuto dire a un collega di aggiungere manualmente una colonna al proprio schema del database locale dopo aver integrato le tue modifiche dal controllo del codice sorgente, hai affrontato il problema che le migrazioni del database risolvono.
La facade Schema
di Laravel fornisce supporto agnostico per creare e manipolare tabelle su tutti i sistemi di database supportati da Laravel. Solitamente, le migrazioni utilizzano questa facade per creare e modificare tabelle e colonne del database.
Generazione delle Migrazioni
Puoi usare il comando make:migration
di Artisan per creare una migrazione del database. La nuova migrazione sarà inserita nella directory database/migrations
. Ogni file di migrazione contiene un timestamp che permette a Laravel di determinare l’ordine delle migrazioni:
php artisan make:migration create_flights_table
Laravel utilizzerà il nome della migrazione per cercare di indovinare il nome della tabella e se la migrazione creerà una nuova tabella. Se Laravel riesce a determinare il nome della tabella dal nome della migrazione, il file di migrazione generato sarà precompilato con la tabella specificata. Altrimenti, potrai specificare manualmente la tabella nel file di migrazione.
Se desideri specificare un percorso personalizzato per la migrazione generata, puoi usare l’opzione --path
quando esegui il comando make:migration
. Il percorso fornito deve essere relativo al percorso base della tua applicazione.
I template delle migrazioni possono essere personalizzati usando la pubblicazione dei stub.
Comprimi le Migrazioni
Man mano che sviluppi la tua applicazione, potresti accumulare sempre più migrazioni nel tempo. Questo può portare a una directory database/migrations
ingombrante con potenzialmente centinaia di migrazioni. Se lo desideri, puoi "comprimere" le tue migrazioni in un unico file SQL. Per iniziare, esegui il comando schema:dump
:
php artisan schema:dump
# Effettua il dump dello schema del database attuale e rimuovi tutte le migrazioni esistenti...
php artisan schema:dump --prune
Quando esegui questo comando, Laravel scriverà un file "schema" nella directory database/schema
della tua applicazione. Il nome del file dello schema corrisponderà alla connessione al database. Ora, quando tenti di migrare il tuo database e nessun’altra migrazione è stata eseguita, Laravel eseguirà prima le istruzioni SQL nel file dello schema della connessione al database che stai utilizzando. Dopo aver eseguito le istruzioni SQL del file dello schema, Laravel eseguirà tutte le migrazioni rimanenti che non facevano parte del dump dello schema.
Se i test della tua applicazione usano una connessione al database diversa da quella che usi normalmente durante lo sviluppo locale, dovresti assicurarti di aver effettuato il dump di un file di schema utilizzando quella connessione al database in modo che i tuoi test possano costruire il tuo database. Potresti voler fare questo dopo aver effettuato il dump della connessione al database che usi normalmente durante lo sviluppo locale:
php artisan schema:dump
php artisan schema:dump --database=testing --prune
Dovresti aggiungere il tuo file di schema del database al controllo del codice sorgente in modo che altri sviluppatori del tuo team possano rapidamente creare la struttura iniziale del database della tua applicazione.
La compressione delle migrazioni è disponibile solo per i database MariaDB, MySQL, PostgreSQL e SQLite e utilizza il client a riga di comando del database.
Struttura delle migration
Una classe di migration contiene due metodi: up
e down
. Il metodo up
viene usato per aggiungere nuove tabelle, colonne o indici al tuo database, mentre il metodo down
deve invertire le operazioni eseguite dal metodo up
.
All’interno di entrambi i metodi, puoi usare il builder Schema
di Laravel per creare e modificare tabelle in modo espressivo. Per conoscere tutti i metodi disponibili sul builder Schema
, consulta la sua documentazione. Ad esempio, la seguente migration crea una tabella flights
:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Esegui le migrations.
*/
public function up(): void
{
Schema::create('flights', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('airline');
$table->timestamps();
});
}
/**
* Annulla le migrations.
*/
public function down(): void
{
Schema::drop('flights');
}
};
Impostare la Connessione della Migrazione
Se la tua migrazione interagisce con una connessione al database diversa dalla connessione predefinita della tua applicazione, dovresti impostare la proprietà $connection
della tua migrazione:
/**
* La connessione al database che deve essere usata dalla migrazione.
*
* @var string
*/
protected $connection = 'pgsql';
/**
* Esegui le migrazioni.
*/
public function up(): void
{
// ...
}
Eseguire le Migrazioni
Per eseguire tutte le migrazioni in sospeso, esegui il comando Artisan migrate
:
php artisan migrate
Se vuoi vedere quali migrazioni sono state eseguite finora, puoi usare il comando Artisan migrate:status
:
php artisan migrate:status
Se vuoi vedere le istruzioni SQL che verranno eseguite dalle migrazioni senza eseguirle realmente, puoi usare l’opzione --pretend
con il comando migrate
:
php artisan migrate --pretend
Isolamento dell’Esecuzione delle Migration
Se stai distribuendo la tua applicazione su più server ed eseguendo migrations come parte del processo di deployment, probabilmente non vuoi che due server tentino di migrare il database allo stesso tempo. Per evitare ciò, puoi usare l’opzione isolated
quando invochi il comando migrate
.
Quando viene fornita l’opzione isolated
, Laravel acquisirà un lock atomico utilizzando il driver di cache della tua applicazione prima di tentare di eseguire le migrations. Tutti gli altri tentativi di eseguire il comando migrate
mentre quel lock è attivo non verranno eseguiti; tuttavia, il comando terminerà comunque con un codice di uscita di successo:
php artisan migrate --isolated
Per utilizzare questa funzionalità, la tua applicazione deve usare il driver di cache
memcached
,redis
,dynamodb
,database
,file
oarray
come driver di cache predefinito. Inoltre, tutti i server devono comunicare con lo stesso server di cache centrale.
Forzare l’esecuzione delle migrazioni in produzione
Alcune operazioni di migrazione possono essere distruttive, il che significa che potrebbero causare la perdita di dati. Per proteggerti dall’esecuzione di questi comandi sul database di produzione, verrà richiesta una conferma prima che i comandi vengano eseguiti. Per forzare l’esecuzione dei comandi senza richiesta, usa l’opzione --force
:
php artisan migrate --force
Annullare le Migrazioni
Per annullare l’ultima operazione di migrazione, puoi usare il comando Artisan rollback
. Questo comando annulla l’ultimo "batch" di migrazioni, che può includere più file di migrazione:
php artisan migrate:rollback
Puoi annullare un numero limitato di migrazioni fornendo l’opzione --step
al comando rollback
. Ad esempio, il seguente comando annullerà le ultime cinque migrazioni:
php artisan migrate:rollback --step=5
Puoi annullare uno specifico "batch" di migrazioni fornendo l’opzione --batch
al comando rollback
, dove l’opzione batch
corrisponde a un valore di batch nella tabella migrations
del tuo database. Ad esempio, il seguente comando annullerà tutte le migrazioni nel batch tre:
php artisan migrate:rollback --batch=3
Se vuoi vedere le istruzioni SQL che verranno eseguite dalle migrazioni senza eseguirle effettivamente, puoi aggiungere l’opzione --pretend
al comando migrate:rollback
:
php artisan migrate:rollback --pretend
Il comando migrate:reset
annullerà tutte le migrazioni della tua applicazione:
php artisan migrate:reset
Ripristina e Esegui le Migrazioni con un Solo Comando
Il comando migrate:refresh
annulla tutte le tue migrazioni e poi esegue il comando migrate
. Questo comando ricrea effettivamente tutto il tuo database:
php artisan migrate:refresh
php artisan migrate:refresh --seed
Puoi annullare e riapplicare un numero limitato di migrazioni fornendo l’opzione step
al comando refresh
. Ad esempio, il comando seguente annullerà e riapplicherà le ultime cinque migrazioni:
php artisan migrate:refresh --step=5
Elimina tutte le tabelle e migra
Il comando migrate:fresh
elimina tutte le tabelle dal database e poi esegue il comando migrate
:
php artisan migrate:fresh
php artisan migrate:fresh --seed
Per impostazione predefinita, il comando migrate:fresh
elimina solo le tabelle dalla connessione di database predefinita. Tuttavia, puoi usare l’opzione --database
per specificare la connessione di database da migrare. Il nome della connessione di database deve corrispondere a una connessione definita nel file di configurazione database
della tua applicazione:
php artisan migrate:fresh --database=admin
Il comando
migrate:fresh
eliminerà tutte le tabelle del database indipendentemente dal loro prefisso. Questo comando deve essere usato con cautela quando si sviluppa su un database condiviso con altre applicazioni.
Tabelle
Creazione delle Tabelle
Per creare una nuova tabella nel database, utilizza il metodo create
sulla facade Schema
. Il metodo create
accetta due argomenti: il primo è il nome della tabella, mentre il secondo è una closure che riceve un oggetto Blueprint
che può essere utilizzato per definire la nuova tabella:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email');
$table->timestamps();
});
Quando crei la tabella, puoi utilizzare uno qualsiasi dei metodi delle colonne del costruttore dello schema per definire le colonne della tabella.
Determinare l’esistenza di Tabelle/Colonne
Puoi verificare l’esistenza di una tabella, una colonna o un indice utilizzando i metodi hasTable
, hasColumn
e hasIndex
:
if (Schema::hasTable('users')) {
// La tabella "users" esiste...
}
if (Schema::hasColumn('users', 'email')) {
// La tabella "users" esiste e ha una colonna "email"...
}
if (Schema::hasIndex('users', ['email'], 'unique')) {
// La tabella "users" esiste e ha un indice unico sulla colonna "email"...
}
Connessione al Database e Opzioni della Tabella
Se vuoi eseguire un’operazione sullo schema su una connessione al database che non è la connessione predefinita dell’applicazione, usa il metodo connection
:
Schema::connection('sqlite')->create('users', function (Blueprint $table) {
$table->id();
});
Inoltre, alcune altre proprietà e metodi possono essere utilizzati per definire aspetti aggiuntivi della creazione della tabella. La proprietà engine
può essere usata per specificare il motore di archiviazione della tabella quando si utilizza MariaDB o MySQL:
Schema::create('users', function (Blueprint $table) {
$table->engine('InnoDB');
// ...
});
Le proprietà charset
e collation
possono essere usate per specificare il set di caratteri e la collation per la tabella creata quando si utilizza MariaDB o MySQL:
Schema::create('users', function (Blueprint $table) {
$table->charset('utf8mb4');
$table->collation('utf8mb4_unicode_ci');
// ...
});
Il metodo temporary
può essere usato per indicare che la tabella deve essere "temporanea". Le tabelle temporanee sono visibili solo alla sessione del database della connessione corrente e vengono eliminate automaticamente quando la connessione viene chiusa:
Schema::create('calculations', function (Blueprint $table) {
$table->temporary();
// ...
});
Se desideri aggiungere un "commento" a una tabella del database, puoi invocare il metodo comment
sull’istanza della tabella. I commenti sulle tabelle sono attualmente supportati solo da MariaDB, MySQL e PostgreSQL:
Schema::create('calculations', function (Blueprint $table) {
$table->comment('Business calculations');
// ...
})
Aggiornare Tabelle
Il metodo table
sulla facade Schema
può essere utilizzato per aggiornare tabelle esistenti. Come il metodo create
, il metodo table
accetta due argomenti: il nome della tabella e una closure che riceve un’istanza di Blueprint
che puoi usare per aggiungere colonne o indici alla tabella:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('users', function (Blueprint $table) {
$table->integer('votes');
});
Rinomina / Eliminazione Tabelle
Per rinominare una tabella del database esistente, utilizza il metodo rename
:
use Illuminate\Support\Facades\Schema;
Schema::rename($from, $to);
Per eliminare una tabella esistente, puoi utilizzare i metodi drop
o dropIfExists
:
Schema::drop('users');
Schema::dropIfExists('users');
Rinominare Tabelle con Chiavi Esterne
Prima di rinominare una tabella, dovresti verificare che eventuali vincoli di chiave esterna sulla tabella abbiano un nome esplicito nei tuoi file di migrazione invece di lasciare che Laravel assegni un nome basato su convenzioni. Altrimenti, il nome del vincolo di chiave esterna farà riferimento al vecchio nome della tabella.
Colonne
Creazione delle Colonne
Il metodo table
sul facade Schema
può essere utilizzato per aggiornare tabelle esistenti. Come il metodo create
, il metodo table
accetta due argomenti: il nome della tabella e una closure che riceve un’istanza di Illuminate\Database\Schema\Blueprint
che puoi usare per aggiungere colonne alla tabella:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('users', function (Blueprint $table) {
$table->integer('votes');
});
Tipi di Colonna Disponibili
Il blueprint del costruttore di schema offre una varietà di metodi che corrispondono ai diversi tipi di colonne che puoi aggiungere alle tue tabelle di database. Ciascuno dei metodi disponibili è elencato nella tabella sottostante:
- bigIncrements
- bigInteger
- binary
- boolean
- char
- dateTimeTz
- dateTime
- date
- decimal
- double
- enum
- float
- foreignId
- foreignIdFor
- foreignUlid
- foreignUuid
- geography
- geometry
- id
- increments
- integer
- ipAddress
- json
- jsonb
- longText
- macAddress
- mediumIncrements
- mediumInteger
- mediumText
- morphs
- nullableMorphs
- nullableTimestamps
- nullableUlidMorphs
- nullableUuidMorphs
- rememberToken
- set
- smallIncrements
- smallInteger
- softDeletesTz
- softDeletes
- string
- text
- timeTz
- time
- timestampTz
- timestamp
- timestampsTz
- timestamps
- tinyIncrements
- tinyInteger
- tinyText
- unsignedBigInteger
- unsignedInteger
- unsignedMediumInteger
- unsignedSmallInteger
- unsignedTinyInteger
- ulidMorphs
- uuidMorphs
- ulid
- uuid
- vector
- year
bigIncrements()
Il metodo bigIncrements
crea una colonna auto-incrementante di tipo UNSIGNED BIGINT
(chiave primaria):
$table->bigIncrements('id');
bigInteger()
Il metodo bigInteger
crea una colonna equivalente a BIGINT
:
$table->bigInteger('votes');
binary()
Il metodo binary
crea una colonna equivalente a BLOB
:
$table->binary('photo');
Quando si utilizza MySQL, MariaDB o SQL Server, è possibile passare gli argomenti length
e fixed
per creare una colonna equivalente a VARBINARY
o BINARY
:
$table->binary('data', length: 16); // VARBINARY(16)
$table->binary('data', length: 16, fixed: true); // BINARY(16)
boolean()
Il metodo boolean
crea una colonna equivalente a BOOLEAN
:
$table->boolean('confirmed');
char()
Il metodo char
crea una colonna equivalente a CHAR
con una lunghezza specificata:
$table->char('name', length: 100);
dateTimeTz()
Il metodo dateTimeTz
crea una colonna equivalente di tipo DATETIME
(con fuso orario) con una precisione opzionale per i secondi frazionari:
$table->dateTimeTz('created_at', precision: 0);
dateTime()
Il metodo dateTime
crea una colonna equivalente a DATETIME
con una precisione opzionale per i secondi frazionari:
$table->dateTime('created_at', precision: 0);
date()
Il metodo date
crea una colonna di tipo DATE
:
$table->date('created_at');
decimal()
Il metodo decimal
crea una colonna equivalente a DECIMAL
con la precisione specificata (numero totale di cifre) e la scala (cifre decimali):
$table->decimal('amount', total: 8, places: 2);
double()
Il metodo double
crea una colonna equivalente a DOUBLE
:
$table->double('amount');
enum()
Il metodo enum
crea una colonna equivalente a ENUM
con i valori validi forniti:
$table->enum('difficulty', ['easy', 'hard']);
float()
Il metodo float
crea una colonna di tipo FLOAT
con la precisione fornita:
$table->float('amount', precision: 53);
foreignId()
Il metodo foreignId
crea una colonna equivalente a UNSIGNED BIGINT
:
$table->foreignId('user_id');
foreignIdFor()
Il metodo foreignIdFor
aggiunge una colonna equivalente a {column}_id
per una determinata classe di modello. Il tipo di colonna sarà UNSIGNED BIGINT
, CHAR(36)
o CHAR(26)
a seconda del tipo di chiave del modello:
$table->foreignIdFor(User::class);
foreignUlid()
Il metodo foreignUlid
crea una colonna equivalente a ULID
:
$table->foreignUlid('user_id');
foreignUuid()
Il metodo foreignUuid
crea una colonna equivalente a UUID
:
$table->foreignUuid('user_id');
geography()
Il metodo geography
crea una colonna equivalente a GEOGRAPHY
con il tipo spaziale specificato e lo SRID (Spatial Reference System Identifier):
$table->geography('coordinates', subtype: 'point', srid: 4326);
Il supporto per i tipi spaziali dipende dal driver del tuo database. Consulta la documentazione del tuo database. Se la tua applicazione utilizza un database PostgreSQL, devi installare l’estensione PostGIS prima di poter utilizzare il metodo
geography
.
geometry()
Il metodo geometry
crea una colonna equivalente a GEOMETRY
con il tipo spaziale specificato e SRID (Spatial Reference System Identifier):
$table->geometry('positions', subtype: 'point', srid: 0);
Il supporto per i tipi spaziali dipende dal driver del tuo database. Consulta la documentazione del tuo database. Se la tua applicazione utilizza un database PostgreSQL, devi installare l’estensione PostGIS prima di poter utilizzare il metodo
geometry
.
id()
Il metodo id
è un alias del metodo bigIncrements
. Di default, il metodo creerà una colonna id
; tuttavia, puoi passare un nome di colonna se vuoi assegnare un nome diverso alla colonna:
$table->id();
increments()
Il metodo increments
crea una colonna UNSIGNED INTEGER
auto-incrementante equivalente come chiave primaria:
$table->increments('id');
integer()
Il metodo integer
crea una colonna equivalente a INTEGER
:
$table->integer('votes');
ipAddress()
Il metodo ipAddress
crea una colonna equivalente a VARCHAR
:
$table->ipAddress('visitor');
Quando si usa PostgreSQL, verrà creata una colonna INET
.
json()
Il metodo json
crea una colonna equivalente JSON
:
$table->json('options');
jsonb()
Il metodo jsonb
crea una colonna equivalente a JSONB
:
$table->jsonb('options');
longText()
Il metodo longText
crea una colonna equivalente a LONGTEXT
:
$table->longText('description');
Quando si utilizza MySQL o MariaDB, puoi applicare un set di caratteri binary
alla colonna per creare una colonna equivalente a LONGBLOB
:
$table->longText('data')->charset('binary'); // LONGBLOB
macAddress()
Il metodo macAddress
crea una colonna destinata a contenere un indirizzo MAC. Alcuni sistemi di database, come PostgreSQL, hanno un tipo di colonna dedicato per questo tipo di dati. Altri sistemi di database utilizzeranno una colonna equivalente come stringa:
$table->macAddress('device');
mediumIncrements()
Il metodo mediumIncrements
crea una colonna auto-incrementante equivalente a UNSIGNED MEDIUMINT
come chiave primaria:
$table->mediumIncrements('id');
mediumInteger()
Il metodo mediumInteger
crea una colonna equivalente a MEDIUMINT
:
$table->mediumInteger('votes');
mediumText()
Il metodo mediumText
crea una colonna equivalente a MEDIUMTEXT
:
$table->mediumText('description');
Quando utilizzi MySQL o MariaDB, puoi applicare un set di caratteri binary
alla colonna per creare una colonna equivalente a MEDIUMBLOB
:
$table->mediumText('data')->charset('binary'); // MEDIUMBLOB
morphs()
Il metodo morphs
è un metodo di comodo che aggiunge una colonna equivalente a {column}_id
e una colonna VARCHAR
equivalente a {column}_type
. Il tipo di colonna per {column}_id
sarà UNSIGNED BIGINT
, CHAR(36)
o CHAR(26)
a seconda del tipo di chiave del modello.
Questo metodo è pensato per essere usato quando si definiscono le colonne necessarie per una relazione polimorfica Eloquent. Nell’esempio seguente, verranno create le colonne taggable_id
e taggable_type
:
$table->morphs('taggable');
nullableTimestamps()
Il metodo nullableTimestamps
è un alias del metodo timestamps:
$table->nullableTimestamps(precision: 0);
nullableMorphs()
Il metodo è simile al metodo morphs; tuttavia, le colonne create saranno "nullable":
$table->nullableMorphs('taggable');
nullableUlidMorphs()
Il metodo è simile al metodo ulidMorphs; tuttavia, le colonne create saranno "nullable":
$table->nullableUlidMorphs('taggable');
nullableUuidMorphs()
Questo metodo è simile al metodo uuidMorphs; tuttavia, le colonne create saranno "nullable":
$table->nullableUuidMorphs('taggable');
rememberToken()
Il metodo rememberToken
crea una colonna che può essere nulla, equivalente a VARCHAR(100)
, destinata a memorizzare il token di autenticazione "ricordami" authentication token:
$table->rememberToken();
set()
Il metodo set
crea una colonna equivalente a SET
con la lista di valori validi forniti:
$table->set('flavors', ['strawberry', 'vanilla']);
smallIncrements()
Il metodo smallIncrements
crea una colonna primaria auto-incrementante di tipo UNSIGNED SMALLINT
:
$table->smallIncrements('id');
smallInteger()
Il metodo smallInteger
crea una colonna equivalente a SMALLINT
:
$table->smallInteger('votes');
softDeletesTz()
Il metodo softDeletesTz
aggiunge una colonna deleted_at
di tipo TIMESTAMP
(con fuso orario) che può essere nulla e con una precisione opzionale dei secondi frazionari. Questa colonna serve a memorizzare il timestamp deleted_at
necessario per la funzionalità di "soft delete" di Eloquent:
$table->softDeletesTz('deleted_at', precision: 0);
softDeletes()
Il metodo softDeletes
aggiunge una colonna deleted_at
di tipo TIMESTAMP
che può essere nulla, con una precisione opzionale per i secondi frazionari. Questa colonna serve a memorizzare il timestamp deleted_at
necessario per la funzionalità di "soft delete" di Eloquent:
$table->softDeletes('deleted_at', precision: 0);
string()
Il metodo string
crea una colonna equivalente a VARCHAR
della lunghezza specificata:
$table->string('name', length: 100);
text()
Il metodo text
crea una colonna equivalente a TEXT
:
$table->text('description');
Quando usi MySQL o MariaDB, puoi applicare un set di caratteri binary
alla colonna per creare una colonna equivalente a BLOB
:
$table->text('data')->charset('binary'); // BLOB
timeTz()
Il metodo timeTz
crea una colonna TIME
(con fuso orario) equivalente, con una precisione opzionale per le frazioni di secondi:
$table->timeTz('sunrise', precision: 0);
time()
Il metodo time
crea una colonna equivalente a TIME
con una precisione opzionale per i secondi frazionari:
$table->time('sunrise', precision: 0);
timestampTz()
Il metodo timestampTz
crea una colonna equivalente a TIMESTAMP
(con fuso orario) con una precisione opzionale dei secondi frazionari:
$table->timestampTz('added_at', precision: 0);
timestamp()
Il metodo timestamp
crea una colonna equivalente a TIMESTAMP
con una precisione opzionale per i secondi frazionari:
$table->timestamp('added_at', precision: 0);
timestampsTz()
Il metodo timestampsTz
crea le colonne created_at
e updated_at
come TIMESTAMP
(con fuso orario) con una precisione opzionale per i secondi frazionati:
$table->timestampsTz(precision: 0);
timestamps()
Il metodo timestamps
crea le colonne created_at
e updated_at
equivalenti a TIMESTAMP
con una precisione facoltativa per i secondi frazionari:
$table->timestamps(precision: 0);
tinyIncrements()
Il metodo tinyIncrements
crea una colonna UNSIGNED TINYINT
auto-incrementante come chiave primaria:
$table->tinyIncrements('id');
tinyInteger()
Il metodo tinyInteger
crea una colonna equivalente a TINYINT
:
$table->tinyInteger('votes');
tinyText()
Il metodo tinyText
crea una colonna equivalente a TINYTEXT
:
$table->tinyText('notes');
Quando si utilizza MySQL o MariaDB, puoi applicare un set di caratteri binary
alla colonna per creare una colonna equivalente a TINYBLOB
:
$table->tinyText('data')->charset('binary'); // TINYBLOB
unsignedBigInteger()
Il metodo unsignedBigInteger
crea una colonna equivalente a UNSIGNED BIGINT
:
$table->unsignedBigInteger('votes');
unsignedInteger()
Il metodo unsignedInteger
crea una colonna equivalente a UNSIGNED INTEGER
:
$table->unsignedInteger('votes');
unsignedMediumInteger()
Il metodo unsignedMediumInteger
crea una colonna equivalente a UNSIGNED MEDIUMINT
:
$table->unsignedMediumInteger('votes');
unsignedSmallInteger()
Il metodo unsignedSmallInteger
crea una colonna equivalente a UNSIGNED SMALLINT
:
$table->unsignedSmallInteger('votes');
unsignedTinyInteger()
Il metodo unsignedTinyInteger
crea una colonna equivalente a UNSIGNED TINYINT
:
$table->unsignedTinyInteger('votes');
ulidMorphs()
Il metodo ulidMorphs
è un metodo di comodità che aggiunge una colonna {column}_id
equivalente a CHAR(26)
e una colonna {column}_type
equivalente a VARCHAR
.
Questo metodo è pensato per essere utilizzato quando si definiscono le colonne necessarie per una relazione polimorfica Eloquent che utilizza identificatori ULID. Nel seguente esempio, verranno create le colonne taggable_id
e taggable_type
:
$table->ulidMorphs('taggable');
uuidMorphs()
Il metodo uuidMorphs
è un metodo comodo che aggiunge una colonna {column}_id
equivalente a CHAR(36)
e una colonna {column}_type
equivalente a VARCHAR
.
Questo metodo è pensato per essere usato quando si definiscono le colonne necessarie per una relazione polimorfica Eloquent che utilizza identificatori UUID. Nell’esempio seguente, verranno create le colonne taggable_id
e taggable_type
:
$table->uuidMorphs('taggable');
ulid()
Il metodo ulid
crea una colonna equivalente a ULID
:
$table->ulid('id');
uuid()
Il metodo uuid
crea una colonna equivalente a UUID
:
$table->uuid('id');
vector()
Il metodo vector
crea una colonna equivalente a vector
:
$table->vector('embedding', dimensions: 100);
year()
Il metodo year
crea una colonna di tipo YEAR
:
$table->year('birth_year');
Modificatori di Colonna
Oltre ai tipi di colonna elencati sopra, ci sono diversi "modificatori" che puoi usare quando aggiungi una colonna a una tabella del database. Ad esempio, per rendere la colonna "nullable", puoi usare il metodo nullable
:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('users', function (Blueprint $table) {
$table->string('email')->nullable();
});
La tabella seguente contiene tutti i modificatori di colonna disponibili. Questa lista non include i modificatori di indice:
Modificatore | Descrizione |
---|---|
->after('column') |
Posiziona la colonna "dopo" un’altra colonna (MariaDB / MySQL). |
->autoIncrement() |
Imposta le colonne INTEGER come auto-incrementanti (chiave primaria). |
->charset('utf8mb4') |
Specifica un set di caratteri per la colonna (MariaDB / MySQL). |
->collation('utf8mb4_unicode_ci') |
Specifica una collation per la colonna. |
->comment('my comment') |
Aggiungi un commento a una colonna (MariaDB / MySQL / PostgreSQL). |
->default($value) |
Specifica un valore "di default" per la colonna. |
->first() |
Posiziona la colonna "prima" nella tabella (MariaDB / MySQL). |
->from($integer) |
Imposta il valore iniziale di un campo auto-incrementante (MariaDB / MySQL / PostgreSQL). |
->invisible() |
Rendi la colonna "invisibile" alle query SELECT * (MariaDB / MySQL). |
->nullable($value = true) |
Permetti l’inserimento di valori NULL nella colonna. |
->storedAs($expression) |
Crea una colonna generata memorizzata (MariaDB / MySQL / PostgreSQL / SQLite). |
->unsigned() |
Imposta le colonne INTEGER come UNSIGNED (MariaDB / MySQL). |
->useCurrent() |
Imposta le colonne TIMESTAMP per usare CURRENT_TIMESTAMP come valore di default. |
->useCurrentOnUpdate() |
Imposta le colonne TIMESTAMP per usare CURRENT_TIMESTAMP quando un record viene aggiornato (MariaDB / MySQL). |
->virtualAs($expression) |
Crea una colonna generata virtuale (MariaDB / MySQL / SQLite). |
->generatedAs($expression) |
Crea una colonna di identità con opzioni di sequenza specificate (PostgreSQL). |
->always() |
Definisce la precedenza dei valori di sequenza sugli input per una colonna di identità (PostgreSQL). |
Espressioni di default
Il modificatore default
accetta un valore o un’istanza di Illuminate\Database\Query\Expression
. Utilizzare un’istanza di Expression
impedirà a Laravel di racchiudere il valore tra virgolette e permetterà di usare funzioni specifiche del database. Una situazione in cui questo è particolarmente utile è quando devi assegnare valori predefiniti alle colonne JSON:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Esegue le migrazioni.
*/
public function up(): void
{
Schema::create('flights', function (Blueprint $table) {
$table->id();
$table->json('movies')->default(new Expression('(JSON_ARRAY())'));
$table->timestamps();
});
}
};
Il supporto per le espressioni di default dipende dal driver del database, dalla versione del database e dal tipo di campo. Consulta la documentazione del tuo database.
Ordine delle colonne
Quando si utilizza il database MariaDB o MySQL, il metodo after
può essere usato per aggiungere colonne dopo una colonna esistente nello schema:
$table->after('password', function (Blueprint $table) {
$table->string('address_line1');
$table->string('address_line2');
$table->string('city');
});
Modificare Colonne
Il metodo change
ti permette di modificare il tipo e gli attributi delle colonne esistenti. Ad esempio, potresti voler aumentare la dimensione di una colonna string
. Per vedere il metodo change
in azione, aumentiamo la dimensione della colonna name
da 25 a 50. Per fare ciò, definiamo semplicemente il nuovo stato della colonna e poi chiamiamo il metodo change
:
Schema::table('users', function (Blueprint $table) {
$table->string('name', 50)->change();
});
Quando modifichi una colonna, devi includere esplicitamente tutti i modificatori che desideri mantenere nella definizione della colonna – qualsiasi attributo mancante verrà rimosso. Ad esempio, per mantenere gli attributi unsigned
, default
e comment
, devi chiamare ogni modificatore esplicitamente quando cambi la colonna:
Schema::table('users', function (Blueprint $table) {
$table->integer('votes')->unsigned()->default(1)->comment('my comment')->change();
});
Il metodo change
non modifica gli indici della colonna. Pertanto, puoi usare i modificatori di indice per aggiungere o rimuovere esplicitamente un indice quando modifichi la colonna:
// Aggiungi un indice...
$table->bigIncrements('id')->primary()->change();
// Rimuovi un indice...
$table->char('postal_code', 10)->unique(false)->change();
Ridenominare le Colonne
Per rinominare una colonna, puoi usare il metodo renameColumn
fornito dallo schema builder:
Schema::table('users', function (Blueprint $table) {
$table->renameColumn('from', 'to');
});
Eliminare Colonne
Per eliminare una colonna, puoi usare il metodo dropColumn
sullo schema builder:
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('votes');
});
Puoi eliminare più colonne da una tabella passando un array di nomi di colonne al metodo dropColumn
:
Schema::table('users', function (Blueprint $table) {
$table->dropColumn(['votes', 'avatar', 'location']);
});
Alias dei Comandi Disponibili
Laravel fornisce diversi metodi utili per eliminare tipi comuni di colonne. Ognuno di questi metodi è descritto nella tabella qui sotto:
Command | Description |
---|---|
$table->dropMorphs('morphable'); |
Elimina le colonne morphable_id e morphable_type . |
$table->dropRememberToken(); |
Elimina la colonna remember_token . |
$table->dropSoftDeletes(); |
Elimina la colonna deleted_at . |
$table->dropSoftDeletesTz(); |
Alias del metodo dropSoftDeletes() . |
$table->dropTimestamps(); |
Elimina le colonne created_at e updated_at . |
$table->dropTimestampsTz(); |
Alias del metodo dropTimestamps() . |
Indici
Creare Indici
Il costruttore di schemi di Laravel supporta diversi tipi di indici. L’esempio seguente crea una nuova colonna email
e specifica che i suoi valori devono essere unici. Per creare l’indice, possiamo concatenare il metodo unique
alla definizione della colonna:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('users', function (Blueprint $table) {
$table->string('email')->unique();
});
In alternativa, puoi creare l’indice dopo aver definito la colonna. Per farlo, devi chiamare il metodo unique
sul blueprint del costruttore di schemi. Questo metodo accetta il nome della colonna che deve ricevere un indice unico:
$table->unique('email');
Puoi anche passare un array di colonne a un metodo di indice per creare un indice composto:
$table->index(['account_id', 'created_at']);
Quando crei un indice, Laravel genererà automaticamente un nome per l’indice basato sulla tabella, sui nomi delle colonne e sul tipo di indice. Tuttavia, puoi passare un secondo argomento al metodo per specificare tu stesso il nome dell’indice:
$table->unique('email', 'unique_email');
Tipi di Indici Disponibili
La classe blueprint del builder dello schema di Laravel offre metodi per creare ogni tipo di indice supportato da Laravel. Ogni metodo per l’indice accetta un secondo argomento opzionale per specificare il nome dell’indice. Se omesso, il nome sarà derivato dai nomi della tabella e della(colonne) usate per l’indice, oltre al tipo di indice. Ognuno dei metodi di indice disponibili è descritto nella tabella sottostante:
Comando | Descrizione |
---|---|
$table->primary('id'); |
Aggiunge una chiave primaria. |
$table->primary(['id', 'parent_id']); |
Aggiunge chiavi composite. |
$table->unique('email'); |
Aggiunge un indice unico. |
$table->index('state'); |
Aggiunge un indice. |
$table->fullText('body'); |
Aggiunge un indice full text (MariaDB / MySQL / PostgreSQL). |
$table->fullText('body')->language('english'); |
Aggiunge un indice full text della lingua specificata (PostgreSQL). |
$table->spatialIndex('location'); |
Aggiunge un indice spaziale (eccetto SQLite). |
Ridenominare gli Indici
Per rinominare un indice, puoi usare il metodo renameIndex
fornito dal blueprint dello schema builder. Questo metodo accetta il nome attuale dell’indice come primo argomento e il nome desiderato come secondo argomento:
$table->renameIndex('from', 'to')
Eliminare gli Indici
Per eliminare un indice, devi specificare il nome dell’indice. Per default, Laravel assegna automaticamente un nome all’indice basato sul nome della tabella, il nome della colonna indicizzata e il tipo di indice. Ecco alcuni esempi:
Comando | Descrizione |
---|---|
$table->dropPrimary('users_id_primary'); |
Elimina una chiave primaria dalla tabella "users". |
$table->dropUnique('users_email_unique'); |
Elimina un indice unico dalla tabella "users". |
$table->dropIndex('geo_state_index'); |
Elimina un indice di base dalla tabella "geo". |
$table->dropFullText('posts_body_fulltext'); |
Elimina un indice full text dalla tabella "posts". |
$table->dropSpatialIndex('geo_location_spatialindex'); |
Elimina un indice spaziale dalla tabella "geo" (tranne SQLite). |
Se passi un array di colonne in un metodo che elimina gli indici, il nome convenzionale dell’indice verrà generato in base al nome della tabella, alle colonne e al tipo di indice:
Schema::table('geo', function (Blueprint $table) {
$table->dropIndex(['state']); // Elimina l'indice 'geo_state_index'
});
Vincoli di Chiave Esterna
Laravel offre il supporto per creare vincoli di chiave esterna, utilizzati per garantire l’integrità referenziale a livello di database. Ad esempio, definiamo una colonna user_id
nella tabella posts
che fa riferimento alla colonna id
nella tabella users
:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('posts', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
Poiché questa sintassi è piuttosto prolissa, Laravel fornisce metodi aggiuntivi e più concisi che utilizzano le convenzioni per offrire una migliore esperienza di sviluppo. Utilizzando il metodo foreignId
per creare la tua colonna, l’esempio sopra può essere riscritto in questo modo:
Schema::table('posts', function (Blueprint $table) {
$table->foreignId('user_id')->constrained();
});
Il metodo foreignId
crea una colonna equivalente a UNSIGNED BIGINT
, mentre il metodo constrained
utilizza le convenzioni per determinare la tabella e la colonna di riferimento. Se il nome della tua tabella non corrisponde alle convenzioni di Laravel, puoi fornirlo manualmente al metodo constrained
. Inoltre, puoi specificare anche il nome che deve essere assegnato all’indice generato:
Schema::table('posts', function (Blueprint $table) {
$table->foreignId('user_id')->constrained(
table: 'users', indexName: 'posts_user_id'
);
});
Puoi anche specificare l’azione desiderata per le proprietà "on delete" e "on update" del vincolo:
$table->foreignId('user_id')
->constrained()
->onUpdate('cascade')
->onDelete('cascade');
È disponibile anche una sintassi alternativa ed esplicativa per queste azioni:
Metodo | Descrizione |
---|---|
$table->cascadeOnUpdate(); |
Gli aggiornamenti devono propagarsi. |
$table->restrictOnUpdate(); |
Gli aggiornamenti devono essere limitati. |
$table->nullOnUpdate(); |
Gli aggiornamenti impostano il valore della chiave esterna su null. |
$table->noActionOnUpdate(); |
Nessuna azione sugli aggiornamenti. |
$table->cascadeOnDelete(); |
Le cancellazioni devono propagarsi. |
$table->restrictOnDelete(); |
Le cancellazioni devono essere limitate. |
$table->nullOnDelete(); |
Le cancellazioni impostano il valore della chiave esterna su null. |
$table->noActionOnDelete(); |
Previene le cancellazioni se esistono record figli. |
Qualsiasi modificatore di colonna aggiuntivo deve essere chiamato prima del metodo constrained
:
$table->foreignId('user_id')
->nullable()
->constrained();
Rimozione delle Foreign Keys
Per rimuovere una foreign key, puoi usare il metodo dropForeign
, passando il nome del vincolo della foreign key da eliminare come argomento. I vincoli delle foreign key seguono la stessa convenzione di denominazione degli indici. In altre parole, il nome del vincolo della foreign key si basa sul nome della tabella e delle colonne nel vincolo, seguito dal suffisso "_foreign":
$table->dropForeign('posts_user_id_foreign');
In alternativa, puoi passare un array contenente il nome della colonna che contiene la foreign key al metodo dropForeign
. L’array verrà convertito in un nome di vincolo della foreign key utilizzando le convenzioni di denominazione di Laravel:
$table->dropForeign(['user_id']);
Attivare e Disattivare i Vincoli di Chiave Esterna
Puoi abilitare o disabilitare i vincoli di chiave esterna nelle tue migrazioni utilizzando i seguenti metodi:
Schema::enableForeignKeyConstraints();
Schema::disableForeignKeyConstraints();
Schema::withoutForeignKeyConstraints(function () {
// Constraints disabled within this closure...
});
SQLite disabilita i vincoli di chiave esterna per impostazione predefinita. Quando usi SQLite, assicurati di abilitare il supporto alle chiavi esterne nella configurazione del tuo database prima di tentare di crearle nelle tue migrazioni.
Eventi
Per comodità, ogni operazione di migrazione emetterà un event. Tutti gli eventi seguenti estendono la classe base Illuminate\Database\Events\MigrationEvent
:
Classe | Descrizione |
---|---|
Illuminate\Database\Events\MigrationsStarted |
Un gruppo di migrazioni sta per essere eseguito. |
Illuminate\Database\Events\MigrationsEnded |
Un gruppo di migrazioni ha terminato l’esecuzione. |
Illuminate\Database\Events\MigrationStarted |
Una singola migrazione sta per essere eseguita. |
Illuminate\Database\Events\MigrationEnded |
Una singola migrazione ha terminato l’esecuzione. |
Illuminate\Database\Events\NoPendingMigrations |
Un comando di migrazione non ha trovato migrazioni in sospeso. |
Illuminate\Database\Events\SchemaDumped |
Un dump dello schema del database è stato completato. |
Illuminate\Database\Events\SchemaLoaded |
Uno schema dump del database esistente è stato caricato. |