Vai al contenuto principale

Introduzione

Laravel 12 è stato rilasciato a febbraio 2025. Questa guida illustra la procedura di aggiornamento da Laravel 11.x a 12.x.
Il tempo stimato necessario all’aggiornamento è di circa 5 minuti. L’impatto dei breaking change sull’applicazione varia in base a dimensione e funzionalità usate.

Aggiornamento automatico con Laravel Shift

Puoi automatizzare l’aggiornamento con Laravel Shift. Shift aggiorna in automatico le dipendenze e i file di configurazione.

Cambiamenti per livello di impatto

Impatto: Alto

  • Aggiornamento delle dipendenze
  • Aggiornamento dell’installer di Laravel

Impatto: Medio

  • Trait HasUuids di Eloquent e UUIDv7

Impatto: Basso

  • Carbon 3
  • Mappatura degli indici dei risultati di Concurrency
  • Risoluzione delle dipendenze di classe nel container
  • Esclusione degli SVG dalla validazione delle immagini
  • Path di root predefinito del disco filesystem locale
  • Ispezione database multi-schema
  • Merge di request con array annidati

Procedura di aggiornamento

Aggiornamento delle dipendenze

Impatto: Alto Aggiorna in composer.json le seguenti dipendenze.
{
  "require": {
    "laravel/framework": "^12.0"
  },
  "require-dev": {
    "phpunit/phpunit": "^11.0",
    "pestphp/pest": "^3.0"
  }
}
Dopo l’aggiornamento, installa le dipendenze con il comando seguente.
composer update

Aggiornamento dell’installer di Laravel

Impatto: Alto Se usi la CLI dell’installer di Laravel per creare nuove app, aggiornalo a una versione compatibile con Laravel 12.x e con i nuovi starter kit. Se l’hai installato con composer global require:
composer global update laravel/installer
Se l’hai installato con php.new, esegui il comando di reinstallazione adatto al tuo sistema operativo.
/bin/bash -c "$(curl -fsSL https://php.new/install/mac/8.4)"
Se usi la versione bundle di Laravel Herd, aggiorna Herd stesso all’ultima release.

Nuovi starter kit

In Laravel 12 sono stati introdotti nuovi starter kit al posto dei precedenti Breeze e Jetstream. Eseguendo laravel new puoi selezionare in modo interattivo lo stack frontend. Starter kit disponibili:
  • React — Inertia 2, React 19, TypeScript, Tailwind 4, shadcn/ui
  • Vue — Inertia 2, Vue Composition API, TypeScript, Tailwind 4, shadcn-vue
  • Svelte — Inertia 2, Svelte 5, TypeScript, Tailwind 4, shadcn-svelte
  • Livewire — Livewire, Tailwind 4, Flux UI
laravel new my-app
Eseguendo il comando ti viene chiesta la selezione dello starter kit. Dopo la selezione, installa le dipendenze e avvia il server di sviluppo.
cd my-app
npm install && npm run build
composer run dev
Se aggiorni un’app esistente, non è necessario reintrodurre uno starter kit. È una modifica per i nuovi progetti.

Modifiche non retrocompatibili (Breaking Changes)

Eloquent

Trait HasUuids e UUIDv7

Impatto: Medio Il trait HasUuids restituisce ora UUID v7 (UUID ordinati). Se vuoi mantenere il precedente comportamento con UUID v4 ordinati, passa al trait HasVersion4Uuids.
use Illuminate\Database\Eloquent\Concerns\HasUuids; // [tl! remove]
use Illuminate\Database\Eloquent\Concerns\HasVersion4Uuids as HasUuids; // [tl! add]
Se usavi già il trait HasVersion7Uuids, passa al trait HasUuids (ora ha lo stesso comportamento).

Validazione

Esclusione degli SVG dalla validazione delle immagini

Impatto: Basso La regola di validazione image non consente più gli SVG per impostazione predefinita. Per consentirli, specificalo esplicitamente.
use Illuminate\Validation\Rules\File;

'photo' => 'required|image:allow_svg'

// oppure
'photo' => ['required', File::image(allowSvg: true)],

Storage

Path di root predefinito del disco filesystem locale

Impatto: Basso Se nel filesystems non definisci esplicitamente il disco local, il path di root predefinito è cambiato da storage/app a storage/app/private. Per mantenere il comportamento precedente, definisci esplicitamente il disco local nel file di configurazione.
// config/filesystems.php
'local' => [
    'driver' => 'local',
    'root' => storage_path('app'),
],

Database

Ispezione database multi-schema

Impatto: Basso Schema::getTables(), Schema::getViews() e Schema::getTypes() restituiscono ora, per impostazione predefinita, i risultati di tutti gli schemi. Per limitarti a uno schema specifico, passa l’argomento schema.
// Tabelle di tutti gli schemi
$tables = Schema::getTables();

// Solo tabelle dello schema 'main'
$tables = Schema::getTables(schema: 'main');
Schema::getTableListing() restituisce ora, per impostazione predefinita, nomi di tabella qualificati dallo schema.
$tables = Schema::getTableListing();
// ['main.migrations', 'main.users', 'blog.posts']

$tables = Schema::getTableListing(schema: 'main', schemaQualified: false);
// ['migrations', 'users']

Modifica della firma del costruttore per il database

Impatto: Molto basso I costruttori di Illuminate\Database\Schema\Blueprint e Illuminate\Database\Grammar richiedono ora un’istanza Connection come primo argomento.
// Laravel <= 11.x
$grammar = new MySqlGrammar;
$grammar->setConnection($connection);

// Laravel >= 12.x
$grammar = new MySqlGrammar($connection);
Inoltre, le seguenti API sono state rimosse o deprecate.
APIStato
Blueprint::getPrefix()Deprecato
Connection::withTablePrefix()Rimosso
Grammar::getTablePrefix() / setTablePrefix()Deprecati
Grammar::setConnection()Rimosso
Ottieni il prefisso della tabella direttamente dalla connessione.
$prefix = $connection->getTablePrefix();

Concurrency

Mappatura degli indici dei risultati

Impatto: Basso Se passi un array associativo a Concurrency::run(), i risultati ora vengono restituiti in corrispondenza delle rispettive chiavi.
$result = Concurrency::run([
    'task-1' => fn () => 1 + 1,
    'task-2' => fn () => 2 + 2,
]);

// ['task-1' => 2, 'task-2' => 4]

Container

Valori predefiniti nella risoluzione delle dipendenze di classe

Impatto: Basso Il container di DI rispetta ora i valori predefiniti delle proprietà della classe quando risolve un’istanza.
class Example
{
    public function __construct(public ?Carbon $date = null) {}
}

$example = resolve(Example::class);

// Laravel <= 11.x: restituisce un'istanza Carbon
// Laravel >= 12.x: restituisce null

Request

Merge di request con array annidati

Impatto: Basso Con $request->mergeIfMissing() puoi ora mergiare dati di array annidati usando la notazione con punti. Prima le chiavi con notazione a punti venivano create direttamente come chiavi di primo livello.
$request->mergeIfMissing([
    'user.last_name' => 'Otwell',
]);

Routing

Priorità delle rotte

Impatto: Basso Il comportamento in presenza di più rotte con lo stesso nome è stato uniformato tra rotte cache e non-cache. Anche nel routing non cache viene ora considerata prioritaria la prima rotta registrata, non l’ultima.

Autenticazione

Modifica del costruttore di DatabaseTokenRepository

Impatto: Molto basso Il costruttore di Illuminate\Auth\Passwords\DatabaseTokenRepository accetta il parametro $expires in secondi, non più in minuti.

Carbon 3

Impatto: Basso Il supporto a Carbon 2.x è stato rimosso. Tutte le app Laravel 12 richiedono Carbon 3.x.

Conclusioni

Laravel 12 è una versione che si aggiorna in modo relativamente fluido. Ecco i punti principali di attenzione.
ModificaImpattoAzione
Aggiornamento delle dipendenze in composer.jsonAltoPassa a laravel/framework ^12.0
Aggiornamento dell’installer di LaravelAltocomposer global update
HasUuids → UUIDv7MedioSe necessario, passa a HasVersion4Uuids
Esclusione degli SVG in imageBassoSe vuoi consentire SVG, aggiungi allow_svg
Cambio del root predefinito del disco localeBassoSpecificalo esplicitamente nel file di configurazione
Carbon 3 richiestoBassoVerifica la compatibilità API

Riferimenti

Ultima modifica il 13 luglio 2026