Cache memoizzata con tag e refresh dei model in Laravel 13.33
Il team di Laravel ha rilasciato la v13.33.0 con il supporto ai tag per la cache memoizzata, un attributo Refreshes dei model che ricarica le colonne generate dopo una scrittura, e altro ancora:
Cache memoizzata con tag
Joost de Bruijn ha contribuito con un metodo tags() allo store della cache memoizzata, così Cache::memo() ora funziona con le cache taggate. Le letture all'interno della stessa richiesta colpiscono il backend della cache una sola volta e da quel momento arrivano dalla memoria:
// Due chiamate, un solo round trip verso Redis
Cache::memo()->tags(['permissions'])->get("permissions:{$user->id}");
Cache::memo()->tags(['permissions'])->get("permissions:{$user->id}");
// Le scritture vanno alla cache taggata e rimuovono la copia memoizzata
Cache::memo()->tags(['permissions'])->put("permissions:{$user->id}", $permissions);
// Il flush del tag cancella anche le voci memoizzate
Cache::memo()->tags(['permissions'])->flush();
Prima di questa release, lo stesso pattern significava avvolgere a mano una chiamata alla cache taggata in una seconda lookup su Cache::store('array'). Laravel News aveva trattato la versione non taggata quando è stata introdotta in Laravel 12.9.
Leggi di più in Memoize Tagged Cache Reads in Laravel. Vedi la #61593 per maggiori dettagli.
Refresh degli attributi del model dopo le scritture
Caleb White ha contribuito con un attributo #[Refreshes] (e una proprietà $refreshes corrispondente) che ricarica colonne specifiche dal database dopo che un model viene creato o aggiornato. È pensato per le colonne virtualAs e storedAs e per altri valori impostati dal database, che altrimenti risultano mancanti o obsoleti sul model in memoria finché non si chiama refresh():
use Illuminate\Database\Eloquent\Attributes\Refreshes;
#[Refreshes('name')]
class User extends Model
{
//
}
$user = User::create(['first_name' => 'Taylor', 'last_name' => 'Otwell']);
$user->name; // "Taylor Otwell" senza chiamare refresh()
Il refresh esegue una sola query, limitata alle colonne elencate, sulla connessione di scrittura. L'attributo accetta un array o nomi di colonna variadici, e la proprietà $refreshes funziona allo stesso modo se non si usano gli attributi. Leggi di più in Refresh Generated Columns After Saving an Eloquent Model.
Vedi la #61523 per maggiori dettagli.
Salvare un vero NULL con AsCollection e AsArrayObject
Zein Ahmad ha contribuito con una modalità nullable() opt-in per i cast AsCollection e AsArrayObject. Assegnare null a uno di questi cast salva la stringa JSON "null" nella colonna, così whereNull() non trova mai la riga. Con nullable(), il cast salva invece un NULL del database:
protected function casts(): array
{
return [
'items' => AsCollection::class, // invariato: salva "null"
'meta' => AsCollection::nullable(), // salva NULL
'options' => AsArrayObject::nullable(),
];
}
Leggi di più in Store NULL Instead of "null" With AsCollection::nullable(). Vedi la #61596 per maggiori dettagli.
inplace() e lock() per le migration degli indici
Sander Muller ha contribuito con un modificatore inplace() per le operazioni su indici e foreign key, insieme a un modificatore lock(), così una migration MySQL può richiedere ALGORITHM=INPLACE e LOCK=NONE invece di ripiegare su una ricostruzione bloccante della tabella:
Schema::table('video_sessions', function (Blueprint $table) {
$table->index('foo', 'foo_index')->inplace()->lock('none');
});
Il modificatore funziona sui seguenti metodi:
index()unique()primary()fullText()spatialIndex()foreign()
Rispecchia il modificatore instant() che le definizioni delle colonne hanno già.
Vedi la #61602 per maggiori dettagli.
Attributi delle Form Request dalle classi padre
Md Sukkur Ali ha corretto gli attributi delle form request, così una request figlia li eredita dalla sua classe padre. PHP non eredita gli attributi, quindi attributi come #[StopOnFirstFailure] su una request base condivisa venivano ignorati da ogni sottoclasse:
#[StopOnFirstFailure]
#[FailOnUnknownFields]
abstract class ApiRequest extends FormRequest
{
//
}
// Ora entrambi gli attributi si applicano
class StorePostRequest extends ApiRequest
{
//
}
Vedi la #61586 per maggiori dettagli.
Disattivare l'uccisione del worker al timeout
Jack Bayliss ha contribuito con un flag Worker::$killOnTimeout. Per impostazione predefinita, un job che supera il proprio timeout uccide l'intero processo worker e il supervisor ne avvia uno nuovo. Impostando il flag su false, il worker lancia invece una TimeoutExceededException, così il job può fare pulizia e il worker continua a girare:
use Illuminate\Queue\Worker;
Worker::$killOnTimeout = false;
Attenzione: un job che avvolge il corpo del proprio handle() in un try/catch generico può inghiottire l'eccezione.
Una PR correlata di Kieran Brown aggiunge Worker::killUsing(), un hook che viene eseguito prima del SIGKILL, così un exit code personalizzato può raggiungere il supervisor (#61622).
Vedi la #61591 per maggiori dettagli.
Gli helper di test mockArtisan() e realArtisan()
Jenthe Noordsij ha contribuito con due helper di test che separano i due compiti di $this->artisan(). Il metodo mockArtisan() restituisce sempre un PendingCommand per le expectation, mentre realArtisan() esegue sempre il comando e restituisce l'exit code come int, così non devi più attivare o disattivare $mockConsoleOutput per passare dall'uno all'altro:
$this->mockArtisan('inspire')
->expectsOutputToContain('Simplicity')
->assertExitCode(0);
$code = $this->realArtisan('migrate', ['--force' => true]);
Vedi la #61588 per maggiori dettagli.
Note di rilascio
Qui sotto puoi vedere l'elenco completo delle nuove funzionalità e degli aggiornamenti, insieme al diff tra la 13.32.0 e la 13.33.0 su GitHub. Le seguenti note di rilascio provengono direttamente dal changelog:
v13.33.0
- [13.x] Rimuove restart_syscalls da pcntl_signal in Worker di @jackbayliss in #61590
- Modifica il momento in cui viene salvato l'hash della password per le sessioni autenticate di @taylorotwell in #61594
- [13.x] Possibilità di disattivare l'uccisione del worker al timeout del job di @jackbayliss in #61591
- [13.x] Corregge le chiavi enum in many() e get() della cache taggata di @Meacue in #61603
- [13.x] Aggiunge il supporto opt-in per salvare un vero NULL su AsCollection/AsArrayObject di @zeinrahmad76 in #61596
- [13.x] Corregge duplicates() di Eloquent Collection con una chiave o una callback di @lazerg in #61597
- Migliora i retry dei job di Cloud di @timacdonald in #61584
- [13.x] Supporta brick/math 0.20 & 1.0 di @jackbayliss in #61382
- [13.x] aggiunge health-start-period ai workflow di @jackbayliss in #61608
- [13.x] Risolve gli attributi delle FormRequest dalle classi padre di @mdsukkur in #61586
- [13.x] Aggiunge order() ai DevCommands di @jackbayliss in #61575
- [13.x] Aggiunge EncodedParameter a RouteUrlGenerator di @bytestream in #61610
- [13.x] Aggiunge il modificatore di algoritmo DDL inplace() per le operazioni su indici e foreign key di @SanderMuller in #61602
- [13.x] Migliora i tipi di valore del metodo put di Collection di @dfinchenko in #61611
- Consente URL relativi per l'hub Mercure di @barryvdh in #61629
- [13.x] Aggiunge opzioni server alle connessioni PostgreSQL di @DGarbs51 in #61627
- [13.x] Rende raggiungibile l'exit code del timeout del worker di @kieranbrown in #61622
- CI MariaDB 11 di @Rhaima96 in #61615
- [13.x] Cache memoizzata con tag di @joostdebruijn in #61593
- Aggiunge il supporto ai protocolli "valkey://" e "valkeys://" di @cweiske in #61635
- [13.x] Corregge i dump dello schema SQLite che contengono shadow table di @jhm-ciberman in #61637
- [13.x] Rende coerente l'ortografia nei docblock di @shaedrich in #61631
- [13.x] Usa
composer require --with-all-dependenciesper installare requisiti aggiuntivi di @crynobone in #61617 - [13.x] Ricostruisce il client phpredis quando una pipeline o una transazione perde la connessione di @maduonline in #61632
- Applica le correzioni di StyleCI di @taylorotwell in #61638
- [13.x] Aggiunge l'opzione
--pretendal comandoinstall:broadcastingdi @crynobone in #61633 - [13.x] Mocking di artisan migliorato di @jnoordsij in #61588
- [13.x] feat: refresh degli attributi configurati dei model dopo le scritture di @calebdw in #61523
- [13.x] Passa un batch aggiornato agli eventi
BatchFinishedeBatchCanceleddi @xurshudyan in #61644 - [13.x] Restituisce un array JSON vuoto da route:list --json quando nessuna route corrisponde di @xurshudyan in #61642
- [13.x] Testa su MariaDB 12.3 di @Rhaima96 in #61641
- [13.x] Usa la view predefinita quando make:notification --markdown non ha un valore di @xurshudyan in #61643
- [13.x] Miglioramenti ai test di @crynobone in #61660
- [13.x] Corregge
LazyCollection::take()con un limite negativo maggiore della collection di @crynobone in #61659 - [13.x] Salta i batch che non possono essere ritentati in queue:retry-batch di @xurshudyan in #61653
- [13.x] Consolida i test sovrapposti di @jasonmccreary in #61648
- [13.x] Corregge i test dipendenti dall'ordine di @jasonmccreary in #61647
- [13.x] Rispetta l'override di FILESYSTEM_DISK durante la configurazione dei dischi Cloud di @DGarbs51 in #61664
- [13.x] Configura le read replica del database di Laravel Cloud di @WendellAdriel in #61665
- [13.x] Rimuove gli header non stringa da NotPwndVerifier di @kylemilloy in #61666
- [13.x] Corregge l'errore ERR invalid cursor restituito quando si chiama
$predisClient->scan(null, ...)usando Redis 7.4 di @crynobone in #61673 - [13.x] Ripristina il query logging quando una callback pretend lancia un'eccezione di @xurshudyan in #61671
- [13.x] aggiunge sole agli higher order proxy di @jackbayliss in #61667
- [13.x] Aggiunge
createQuietlyecreateManyQuietlyaBelongsToManydi @xurshudyan in #61669 - [13.x] Corregge i valori delle espressioni di binding di
whereValueBetween()di @xurshudyan in #61670 - [13.x] Aggiunge il pooling nativo opt-in di Postgres per Laravel Cloud di @DGarbs51 in #61668
Fonte originale:
https://laravel-news.com/laravel-13-33-0Altri articoli recenti
Laravel AI 1.1 e 1.2: Agent Skills, Cohere e structured output più solidi
Le release 1.1.0 e 1.2.0 di laravel/ai portano gli Agent Skills, l'approvazione obbligatoria per i tool built-in e nuovi provider come Cohere e Laya self-hosted. Sul fronte qualità arrivano i fix allo structured output per Bedrock e il supporto alle provider options. Aggiornati anche i modelli di default, con Claude 4.7+ che ignora i sampling params.
Laravel 13.35.0: scheduler più controllabile, code più flessibili e response Markdown
Laravel 13.35.0 porta Schedule::alwaysOnOneServer(), il supporto a schedule:interrupt per i comandi di lunga durata, --memory in percentuale per queue:work e il nuovo metodo markdown() sulla response factory. Tante piccole migliorie anche a test, view compilate in parallelo e dischi local.
BashBox: un interprete Bash in sandbox per agenti AI in PHP
BashBox è un interprete bash scritto in puro PHP che permette di eseguire gli script generati dagli agenti AI senza mai ricorrere a proc_open, exec o shell_exec. Ogni comando è una classe PHP che lavora su un filesystem virtuale, con limiti di esecuzione, quote disco e accesso di rete configurabili. Ideale per chi sviluppa agenti con il Laravel AI SDK o altre librerie simili.