Laravel 13.25 adds a global pause switch that stops every queue on every connection with one command, replaces the process runner behind
artisan dev
with a tabbed terminal UI, and lets an
Image
instance be returned directly from a route. The Laravel team released v13.25.0 on August 11, 2026.
queue:pause --all和queue:resume --all, plusQueue::pauseAll()和Queue::resumeAll()artisan devruns through@laravel/multiplexwith tabs, stream, and inline modesImage实现Responsable, gainsImage::fromStream(), 和toFormat()is now public- A
UniqueJobSkippedevent, the timeout value onJobTimedOut, and fail-on-timeout for notifications withoutCookies()on responses and aforeignUlidFor()schema helperRequest::all()now prefers input over files when the two collide
什么是新的
Pause Every Queue on Every Connection
Laravel has been able to pause an individual queue for a while, but the granularity worked against you during a deployment. An application with a dozen workers spread over several named queues had to pause each connection and queue pair by name, and those names change as features come and go. Reaching for maintenance mode instead takes the whole site down when all you wanted was for workers to stop reserving jobs.
Both console commands now take an
--all
旗帜:
php
工匠
队列:暂停
- 全部php
工匠
queue:resume
- 全部
The queue argument became optional to make room for it, and the same switch is available on the facade:
使用
Illuminate\Support\Facades\Queue
;队列
::
pauseAll
();队列
::
resumeAll
();
The global switch is a single cache key that workers check alongside the per-queue keys, so
isPaused()
和
getPausedQueues()
report a queue as paused when either switch is on. The two are independent:
resumeAll()
clears the global flag and leaves anything you paused individually still paused, which is deliberate so a deploy script cannot accidentally restart a queue somebody parked on purpose.
Two new events,
QueuesPaused
和
QueuesResumed
, fire alongside the existing per-queue
QueuePaused
和
QueueResumed
. Contributed by
@jackbayliss
在
#61126
。
阅读更多: Pause All Laravel Queues During a Deploy
artisan dev
Runs Through
@laravel/multiplex
这
artisan dev
命令
shelled out to
concurrently
, which interleaves every process into one scrolling feed. A Vite rebuild and a queue worker and Pail all writing at once makes finding the line you care about a scrolling exercise.
It now runs through
@laravel/multiplex
, a terminal UI with each process in its own tab, search, per-process restart and log clearing, and automatic restart of a process that crashes. Three modes are available,
tabs
(默认),
stream
(one interleaved feed you can scroll and search), and
inline
(plain output, used automatically when there is no TTY). Pick one per run:
php
工匠
开发
--streamphp
工匠
开发
--timestamps
--no-restart
Or set the default for the project in a service provider:
使用
Illuminate\Foundation\DevCommands
;DevCommands
::
溪流
();DevCommands
::
带有时间戳
();DevCommands
::
disableAutoRestart
();DevCommands
::
bufferSize
(
5000
(英文):
When the command exits, the buffered logs are printed to the main terminal so nothing is lost on the way out. Windows falls back to
concurrently
, since multiplex currently supports macOS and Linux only, and the Node floor for the new path is v22.13. The full list of modes, flags, and registration methods is in
the artisan dev terminal UI
. Contributed by
@joetannenbaum
在
#61100
。
Images as HTTP Responses
这
first-party image API
could transform an image and store it, but handing one back over HTTP meant calling
toBytes()
and assembling the response yourself.
Image
now implements
Responsable
, so a route can return the instance:
使用
Illuminate\Support\Facades\Image
;路线
::
得到
(
'/avatars/{user}'
,
功能
(
用户
$user) {
返回
图像
::
fromStorage
($用户)
->
avatar_path)
->
cover
(
200
,
200
)
->
toWebp
()
->
质量
(
80
(英文):});
toResponse()
returns a 200 with the processed bytes and a
Content-Type
read from the output, so the header matches whatever format the pipeline produced rather than the source file.
Two smaller additions in the same area.
Image::fromStream()
builds an instance from a stream resource, reading it lazily and throwing an
ImageException
if the stream yields nothing:
$图像
=
图像
::
来自流
(
贮存
::
磁盘
(
's3'
)
->
readStream
($path));
和
toFormat()
is now public, which replaces the
match
statement you would otherwise write to turn a user-supplied format string into the right
toWebp()
或者
toAvif()
称呼:
返回
图像
::
fromUpload
请求
->
文件
(
'照片'
))
->
toFormat
请求
->
细绳
(
'格式'
))
->
质量
(
80
(英文):
An unsupported format throws an
ImageException
rather than falling through. All three contributed by
@calebdw
在
#61111
,
#61109
, 和
#61110
。
Queue Observability Additions
A job that is not dispatched because a
ShouldBeUnique
lock is held disappears without a trace, which makes it hard to tell a working uniqueness constraint from a lock that is never released. The new
UniqueJobSkipped
event carries the job that was dropped:
使用
Illuminate\Queue\Events\UniqueJobSkipped
;事件
::
听
(
功能
(
UniqueJobSkipped
$event) {
日志
::
信息
(
'Skipped unique job'
,[
'工作'
=>
$事件
->
工作
::班级
]);});
It fires from
PendingDispatch
when the unique lock cannot be acquired, alongside the existing
JobDebounced
event (
#61039
)。
JobTimedOut
gained a third property,
$timeout
, holding the number of seconds that was exceeded. A worker started with
queue:work --timeout=120
applies its own timeout to every job it runs, so without the value on the event there was no way to tell a job's own timeout from the worker's (
#61060
)。
Notifications now honor fail-on-timeout.
SendQueuedNotifications
reads a
$failOnTimeout
property or a
#[FailOnTimeout]
attribute off the notification, which matters when a timeout leaves you unsure whether a third party already delivered the message (
#61072
):
使用
Illuminate\Queue\Attributes\FailOnTimeout
;#[
FailOnTimeout
]班级
订单已发货
延伸
通知
实现
应该排队{
//}
Finally,
QueueFake
now assigns a uuid to faked jobs, so the
queue inspection methods
return the same shape they do against a real driver and application code that reads
$job->uuid
is testable (
#60966
)。
withoutCookies()
on Responses
Expiring several cookies meant chaining
withoutCookie()
once per name. The plural form takes an array:
返回
回复
(
'OK'
)
->
withoutCookies
([
'会议'
,
'追踪'
,
“偏好”
]);
It loops over
withoutCookie()
, so the optional
$path
和
$domain
arguments apply to every cookie in the array, and cookie instances work as well as names. Contributed by
@khurshudyan
在
#61115
。
foreignUlidFor()
Schema Helper
foreignIdFor()
already detects the
HasUlids
trait and produces a ULID column, but there was no explicit helper to match
foreignUuidFor()
. The trio is now complete:
$表
->
foreignUlidFor
(
用户
::班级
)
->
受限制
();
The helper infers the column name, the related table, and the referenced key from the model, producing a
char(26)
column and the matching foreign key constraint. Contributed by
@talaridisTh
在
#61036
。
Request::all()
Prefers Input Over Files
Request::all()
merged the input bag and the file bag with
array_replace_recursive()
, with files applied last, so a file field and an input field sharing a name resolved to the
UploadedFile
. The order is now reversed, and input wins:
// POST with input email=taylor@laravel.com and a file also named email$请求
->
全部
();
// ['email' => 'taylor@laravel.com']$请求
->
电子邮件;
// 'taylor@laravel.com'$请求
->
文件
(
'电子邮件'
)
// still the UploadedFile
Nested keys merge the same way, so a
profile.avatar
file and a
profile.name
input still both appear, with input taking precedence only where the keys actually collide.
file()
is unaffected. Contributed by
@泰勒韦尔
在
#61099
。
其他修复和改进
Http::globalOptions()and global middleware were applied to the framework's own cloud agent unix socket long poll, where an option likeforce_ip_resolve => v4breaks the socket connection. A newFactory::withoutGlobalConfiguration()closure isolates agent traffic from application-level client configuration ( #61064 , #61068 )- Queued broadcast events lost the
truedefault for$deleteWhenMissingModels, so a model deleted before the worker picked up the job failed with aModelNotFoundExceptioninstead of being discarded ( #61074 ) Gate::forUser()copied abilities, policies, and callbacks but not the configured default denial response, so a gate set up withResponse::denyAsNotFound()fell back to the framework default ( #61087 )Str::substrReplace()threw aTypeErroron array arguments after the multibyte rewrite passed them straight tomb_substr(). Array calls now delegate to PHP's nativesubstr_replace()( #61105 )- Backed enum queue names are respected when queueing mailables (
#61066
), queue drivers match the fake for enum queue names (
#61116
),
MailFakepreserves queue resolution on queued mailables ( #61114 ), and bulk pushes toDatabaseQueuerespect after-commit dispatch ( #60996 ) - Deactivating cache-backed maintenance mode between the middleware's two cache lookups threw a
TypeError; the middleware now rechecks the state the same way it already did for the file driver ( #61121 ) Container::callleft entries on the build stack when a dependency threw, so later resolutions saw a stale stack ( #61041 )- Typed cache getters interpolated an enum key into the type mismatch message, producing an
Errorinstead of the intendedInvalidArgumentException( #61056 ) - HEIC files reported incorrect dimensions (
#61010
),
LazyCollection::flip()skips values that cannot be array keys ( #61081 ), 和#[WithoutTimestamps]is checked when a model decides whether to touch ( #61073 ) - Retry callbacks on asynchronous HTTP requests receive the HTTP method as a third argument, matching synchronous requests, which previously caused an
ArgumentCountError( #61106 ) - Non-stream resources are rejected in HTTP fake response bodies ( #61047 ), the Cloud log driver sets a socket timeout ( #61065 , #61082 ), and signed URL support was adjusted for Vapor ( #61129 )
schedule:listconverts timezones correctly for range, step, and wildcard cron expressions ( #60913 ),Factory::insert()handles a count of zero ( #60911 ), and a failure while logging a deprecation no longer escalates to a fatal error ( #60907 )- Type annotation fixes for
Arr::prependKeysWith()( #61034 ),Str::numbers()( #61053 ),getMigrationBatches()( #60973 ),getRememberToken()( #61067 ), the route binding registrar ( #61124 ), 和ColumnDefinition::unsigned()( #61123 ) - 支持
brick/math^0.19 ( #61133 )
参考






