310 lines
8.5 KiB
Markdown
310 lines
8.5 KiB
Markdown
# Changelog
|
||
|
||
New updates and improvements to Laravel’s open source products.
|
||
|
||
## July 2025
|
||
|
||
## Laravel Framework 12.x
|
||
|
||
### Added Verbose Output for `queue:work`
|
||
|
||
Pull requests by [@seriquynh](https://github.com/laravel/framework/pull/56086)
|
||
& [@amirhshokri](https://github.com/laravel/framework/pull/56095)
|
||
|
||
|
||
|
||
1php artisan queue:work --verbose
|
||
|
||
2// App\Jobs\UrgentAction 85 high
|
||
|
||
3// App\Jobs\NormalAction 84 default
|
||
|
||
|
||
php artisan queue:work --verbose
|
||
// App\Jobs\UrgentAction 85 high
|
||
// App\Jobs\NormalAction 84 default
|
||
|
||
With `--verbose`, you’ll now see queue names alongside each job and job ID,
|
||
making multi-queue debugging straightforward and saving you time when tracing
|
||
issues.
|
||
|
||
### `Uri` Implements `JsonSerializable`
|
||
|
||
Pull request by
|
||
[@devajmeireles](https://github.com/laravel/framework/pull/56097)
|
||
|
||
|
||
|
||
1echo json_encode(new Uri('/path?x=1'));
|
||
|
||
2// "http://localhost:8000/path?x=1"
|
||
|
||
|
||
echo json_encode(new Uri('/path?x=1'));
|
||
// "http://localhost:8000/path?x=1"
|
||
|
||
This release fixes a serialization bug, properly converting the URI to a
|
||
string when serializing a larger JSON object that contains the URI as a value.
|
||
|
||
### Added `doesntStartWith()` & `doesntEndWith()` `Str` Methods
|
||
|
||
Pull request by
|
||
[@balboacodes](https://github.com/laravel/framework/pull/56168)
|
||
|
||
|
||
|
||
1str('apple')->doesntStartWith('b'); // true
|
||
|
||
2str('apple')->doesntEndWith('e'); // false
|
||
|
||
|
||
str('apple')->doesntStartWith('b'); // true
|
||
str('apple')->doesntEndWith('e'); // false
|
||
|
||
The inverse of `startsWith`/`endsWith`, these new methods allow you to
|
||
fluently test for starting and ending characters in your string.
|
||
|
||
### Closure Support in `pluck()`
|
||
|
||
Pull request by [@ralphjsmit](https://github.com/laravel/framework/pull/56188)
|
||
|
||
|
||
|
||
1$users->pluck(fn($u) => $u->email, fn($u) => strtoupper($u->name));
|
||
|
||
|
||
$users->pluck(fn($u) => $u->email, fn($u) => strtoupper($u->name));
|
||
|
||
You can now dynamically generate keys and values via callbacks. Instead of
|
||
mapping then plucking, you get a single, flexible method that reduces steps
|
||
and keeps intent clear.
|
||
|
||
## Pint
|
||
|
||
### Added `--parallel` Option
|
||
|
||
Pull request by [@nunomaduro](https://github.com/laravel/pint/pull/376)
|
||
|
||
|
||
|
||
1./vendor/bin/pint --parallel
|
||
|
||
|
||
./vendor/bin/pint --parallel
|
||
|
||
By leveraging PHP CS Fixer’s parallel runner,
|
||
[Pint](https://laravel.com/docs/12.x/pint) now formats files concurrently. On
|
||
large codebases that once took minutes, you’ll see results in seconds,
|
||
speeding up both local workflows and CI pipelines for a clear quality of life
|
||
win.
|
||
|
||
## Telescope
|
||
|
||
### Migrated to Vite
|
||
|
||
Pull request by [@nckrtl](https://github.com/laravel/telescope/pull/1598)
|
||
|
||
Telescope’s frontend now uses [Vite](https://laravel.com/docs/12.x/vite)
|
||
instead of Mix. Asset builds finish faster, hot-reloads are more reliable, and
|
||
you benefit from a modern toolchain without changing your workflow.
|
||
|
||
## Octane
|
||
|
||
### FrankenPHP’s File Watcher
|
||
|
||
Pull request by [@kohenkatz](https://github.com/laravel/octane/pull/971)
|
||
|
||
[Octane](https://laravel.com/docs/12.x/octane) now relies on
|
||
[FrankenPHP](https://frankenphp.dev)’s native file watcher for reloading the
|
||
server on file changes. This removes the NodeJS dependency and eases the local
|
||
development process significantly.
|
||
|
||
## Inertia
|
||
|
||
### Reset Form State and Clear Errors with a Single Method
|
||
|
||
Pull request by
|
||
[@pascalbaljet](https://github.com/inertiajs/inertia/pull/2414)
|
||
|
||
|
||
|
||
1const form = useForm({ name: "", email: "" });
|
||
|
||
2
|
||
|
||
3// Instead of:
|
||
|
||
4form.reset();
|
||
|
||
5form.clearErrors();
|
||
|
||
6
|
||
|
||
7// You can now:
|
||
|
||
8form.resetAndClearErrors();
|
||
|
||
|
||
const form = useForm({ name: "", email: "" });
|
||
|
||
// Instead of:
|
||
form.reset();
|
||
form.clearErrors();
|
||
|
||
// You can now:
|
||
form.resetAndClearErrors();
|
||
|
||
You can now concisely reset all fields and errors in one go, bringing your
|
||
form back to square one.
|
||
|
||
### Prevent Minifying JavaScript Builds and Test Apps
|
||
|
||
Pull request by
|
||
[@pascalbaljet](https://github.com/inertiajs/inertia/pull/2424)
|
||
|
||
Inertia no longer distributes minified builds, aligning it with the strategy
|
||
of other popular libraries. This makes debugging more straightforward and
|
||
allows for local patching if the need arises.
|
||
|
||
## June 2025
|
||
|
||
## Laravel Framework 12.x
|
||
|
||
### Added `encrypt()` and `decrypt()` String Helper Methods
|
||
|
||
Pull request by
|
||
[@KIKOmanasijev](https://github.com/laravel/framework/pull/55931)
|
||
|
||
You can now chain `encrypt()` and `decrypt()` directly on a `Str` instance, so
|
||
instead of piping your string through separate encryption calls, you can
|
||
write:
|
||
|
||
|
||
|
||
1$value = Str::of('secret')->encrypt()->prepend('Encrypted: ');
|
||
|
||
2$original = Str::of($value)->decrypt();
|
||
|
||
|
||
$value = Str::of('secret')->encrypt()->prepend('Encrypted: ');
|
||
$original = Str::of($value)->decrypt();
|
||
|
||
This keeps your string-manipulation chains concise (no need to write separate,
|
||
extra code to handle encryption) and you don’t have to manually wrap a value
|
||
in encryption calls each time.
|
||
|
||
Learn more about [`encrypt`](https://laravel.com/docs/12.x/helpers#method-
|
||
encrypt) and [`decrypt`](https://laravel.com/docs/12.x/helpers#method-decrypt)
|
||
|
||
### Added `broadcast_if()` and `broadcast_unless()` Utilities
|
||
|
||
Pull request by
|
||
[@taylorotwell](https://github.com/laravel/framework/pull/55967)
|
||
|
||
You now have two methods for conditional broadcasting in a single call:
|
||
|
||
|
||
|
||
1broadcast_if($order->isPaid(), new OrderShipped($order));
|
||
|
||
2broadcast_unless($user->isActive(), new InactiveUserAlert($user));
|
||
|
||
|
||
broadcast_if($order->isPaid(), new OrderShipped($order));
|
||
broadcast_unless($user->isActive(), new InactiveUserAlert($user));
|
||
|
||
This replaces multi-line conditionals around `broadcast()` and makes your
|
||
event logic more readable, improving the overall developer experience.
|
||
|
||
Read the docs about [event broadcasting in
|
||
Laravel](https://laravel.com/docs/12.x/broadcasting)
|
||
|
||
### Added `--batched` Flag to `make:job`
|
||
|
||
Pull request by
|
||
[@hafezdivandari](https://github.com/laravel/framework/pull/55929)
|
||
|
||
The `php artisan make:job` command now accepts a `--batched` option:
|
||
|
||
|
||
|
||
1php artisan make:job ProcessPodcast --batched
|
||
|
||
|
||
php artisan make:job ProcessPodcast --batched
|
||
|
||
This command scaffolds the job with the `Batchable` trait already applied, so
|
||
you don’t have to add it manually. It saves you a manual step and ensures
|
||
consistency.
|
||
|
||
Learn more about [defining batchable
|
||
jobs](https://laravel.com/docs/12.x/queues#defining-batchable-jobs)
|
||
|
||
## VS Code Extension
|
||
|
||

|
||
|
||
### Memory Improvements
|
||
|
||
Pull request by [@joetannenbaum](https://github.com/laravel/vs-code-
|
||
extension/pull/402)
|
||
|
||
We fixed a memory-leak issue in the extension’s background processes, reducing
|
||
its long-term footprint and preventing slowdowns during extended coding
|
||
sessions.
|
||
|
||
### Improved Startup Time
|
||
|
||
Pull request by [@joetannenbaum](https://github.com/laravel/vs-code-
|
||
extension/pull/404)
|
||
|
||
Initialization with the VS Code extension now completes in under one second
|
||
(down from 5–7 seconds) by deferring heavy setup until it’s actually needed.
|
||
You’ll notice the extension loads almost instantly so you can start building
|
||
faster.
|
||
|
||
Get started with the [Laravel VS Code
|
||
extension](https://github.com/laravel/vs-code-extension)
|
||
|
||
## Inertia
|
||
|
||
### Allow `deepMerge` on Custom Properties
|
||
|
||
Pull request by [@mpociot](https://github.com/inertiajs/inertia/pull/2344)
|
||
|
||
When implementing infinite scrolling with Inertia or other paginated data
|
||
merges, you can now specify a key (`matchOn`) to do a deep merge, matching
|
||
items by ID and replacing or appending as appropriate. This provides greater
|
||
flexibility, prevents duplicated entries, and keeps your client-side data
|
||
consistent.
|
||
|
||
|
||
|
||
1Inertia::render('Users/Index', [
|
||
|
||
2 'users' => Inertia::deepMerge($users)->matchOn('data.id'),
|
||
|
||
3]);
|
||
|
||
|
||
Inertia::render('Users/Index', [
|
||
'users' => Inertia::deepMerge($users)->matchOn('data.id'),
|
||
]);
|
||
|
||
[Learn more in the Inertia docs](https://inertiajs.com/merging-props#server-
|
||
side)
|
||
|
||
### Prevent Duplicate Render in React
|
||
|
||
Pull request by
|
||
[@pascalbaljet](https://github.com/inertiajs/inertia/pull/2377)
|
||
|
||
We fixed a React-specific issue in `<StrictMode>` where the initial Inertia
|
||
page would render twice. Now you get a single, clean first render without
|
||
flicker, improving perceived performance.
|
||
|
||
Get started with the [Laravel + React Starter
|
||
Kit](https://www.youtube.com/watch?v=_sw61Ew1FHQ)
|
||
|