Laravel 9.31 Released
Published on by Paul Redmond
The Laravel team released 9.31 with a request lifecycle duration handler, update model without changing timestamps, fake batches for testing, and more:
Request lifecycle duration handler
Tim MacDonald contributed a callback handler when a request lifecycle is longer than a given time limit:
use Carbon\CarbonInterval as Interval;use Illuminate\Contracts\Http\Kernel; public function boot(){ if ($this->app->runningInConsole()) { return; } $kernel = $this->app[Kernel::class]; $kernel->whenRequestLifecycleIsLongerThan( Interval::seconds(1), fn ($startedAt, $request, $response) => /* ... */ );}
This callback is similar to the cumulative database query time released in Laravel 9.18 Released, but for the request lifecycle.
Model "without timestamps" feature
Tim MacDonald contributed a static withoutTimestamps()
method where updated_at
will not change:
$user = User::first(); // `updated_at` is not changed... User::withoutTimestamps( fn () => $user->update(['reserved_at' => now()]));
Vite manifestHash function
Enzo Innocenzi contributed a manifestHash()
method to the Vite
class, that returns a unique hash if the manifest exists. This can be used to invalidate assets. See Pull Request #44136 for further details.
Fake batches
Taylor Otwell contributed fake batches:
It's currently hard to test things like if a batch was cancelled by a job or if a job added additional jobs to a batch. You have to create a FakeBatch manually and override the cancel / add methods, etc.
This solves that.
[$job, $batch] = (new TestJob)->withFakeBatch(); $job->handle(); $this->assertTrue($batch->cancelled());$this->assertNotEmpty($batch->added);
Model getAppends() method
Arturo Rodríguez added an accessor method to Model to get the accessors that are being appended to model arrays. This could be useful for custom model mappings:
$model->getAppends();
Str wrap static method
Steve Bauman added a missing static Str::wrap()
method, which was only available via Stringable
:
Str::wrap('-bar-', 'foo', 'baz'); // 'foo-bar-baz'str('-bar-')->wrap('foo', 'baz'); // 'foo-bar-baz'
Macroable vite
Tim MacDonald contributed the Macroable
trait to Illuminate\Foundation\Vite
to create aliases matching your JS config:
Vite::macro('image', fn ($asset) => $this->asset("resources/images/{$asset}")); // Usage: <img src="{{ Vite::image('profile.png') }}" ... >
See Pull Request #44198 for further details.
Release Notes
You can see the complete list of new features and updates below and the diff between 9.30.0 and 9.31.0 on GitHub. The following release notes are directly from the changelog:
v9.31.0
Added
- Added unique deferrable initially deferred constants for PostgreSQL (#44127)
- Request lifecycle duration handler (#44122)
- Added Model::withoutTimestamps(...) (#44138)
- Added manifestHash function to Illuminate\Foundation\Vite (#44136)
- Added support for operator <=> in
/Illuminate/Collections/Traits/EnumeratesValues::operatorForWhere()
(#44154) - Added that Illuminate/Database/Connection::registerDoctrineType() can accept object as well as classname for new doctrine type (#44149)
- Added Fake Batches (#44104, #44173)
- Added
Model::getAppends()
(#44180) - Added missing Str::wrap() static method (#44207)
- Added require
symfony/uid
(#44202) - Make Vite macroable (#44198)
Fixed
- Async fix in
Illuminate/Http/Client/PendingRequest
(#44179) - Fixes artisan serve command with PHP_CLI_SERVER_WORKERS environment variable (#44204)
- Fixed
InteractsWithDatabase::castAsJson($value)
incorrectly handles SQLite Database (#44196)