编程 Laravel 13.35 更新笔记:QUERY 路由、defaults() 与百分比内存限制

2026-10-10 21:03:41

Laravel 13.35 更新笔记:QUERY 路由、defaults() 与百分比内存限制

Route::query():为 HTTP QUERY 方法注册路由

Joel Butcher 提交的 Route::query() 为 HTTP QUERY 方法注册路由。QUERY 是一种安全方法,但允许携带请求体,适合筛选条件太长、塞不进 query string 的搜索接口:

Route::query('/products/search', SearchProductsController::class);

QUERY 已加入路由器的动词列表,因此 Route::any() 与 Route::redirect() 也会匹配它。它不在 Registrar contract 中,而 CSRF 保护对 QUERY 请求的校验与 POST 一致:位于 web 中间件组里的 QUERY 路由需要 CSRF token,或者把该路由加入 except 列表。见 PR #61797。

Model defaults():用 HasDefaultAttributes 提供默认值

Wes Hooper 带来的 defaults() 是 $attributes 属性的方法版本,默认值因此可以来自 config、feature flag 或当前日期。在 Laravel 13 中,模型需要显式使用 HasDefaultAttributes trait:

use Illuminate\Database\Eloquent\Concerns\HasDefaultAttributes;

class Subscription extends Model
{
    use HasDefaultAttributes;

    protected function defaults(): array
    {
        return [
            'cancelled' => false,
            'trial_days' => Feature::active('extended-trials') ? 30 : 14,
        ];
    }
}

通过 trait 引入,可以避免影响已经存在名为 defaults() 方法的模型。defaults() 返回的值优先于 $attributes,并且是原始值,会跳过 cast 与 mutator。见 PR #61813。

Fake 断言支持属性数组

Jack Bayliss 让 Queue、Bus、Event 和 Notification 的 fake 在原本接受回调的位置,也可以接受一个预期属性值数组:

Queue::assertPushed(ProcessPodcast::class, [
    'podcast' => $podcast,
    'user' => $user,
    'status' => 'pending',
]);

每个值都按严格相等比较,Eloquent 模型例外,按 is() 比较。参与比较的属性需要是 public。见 PR #61770。

queue:work --memory 支持百分比

--memory 选项现在接受 PHP memory_limit 的百分比:

php artisan queue:work --memory=60%

当 memory_limit 为 512M 时,worker 在某个任务结束后占用约 307 MB 就会停止。如果 memory_limit 为 -1(PHP CLI 下常见),百分比会解析为负数,worker 永远不会因内存而停止。使用百分比时,需要为 worker 进程设置 memory_limit。见 PR #61753。

Schedule::alwaysOnOneServer()

Jack Bayliss 新增的 Schedule::alwaysOnOneServer() 会对每个计划任务应用 onOneServer():

// in AppServiceProvider::boot()
Schedule::alwaysOnOneServer();

没有名字的闭包任务会被跳过,因为 onOneServer() 需要名字来构建锁。该功能依赖所有服务器共享的 cache store。见 PR #61789。

部署时中断长时间运行的调度命令

cyppe 将 schedule:interrupt 改为存储时间戳(与 queue:restart 类似),并新增 Schedule::hasBeenInterruptedSince(),让长时间运行的命令可以在安全位置主动停止:

public function handle(Schedule $schedule)
{
    $startedAt = now();

    foreach ($this->batches() as $batch) {
        if ($schedule->hasBeenInterruptedSince($startedAt)) {
            return;
        }

        $this->process($batch);
    }
}

见 PR #61764。

response()->markdown()

Ashot Gharakeshishyan 新增的 response()->markdown() 与请求侧的 wantsMarkdown() 配套:

return $request->wantsMarkdown()
    ? response()->markdown($post->markdown)
    : view('posts.show', ['post' => $post]);

它返回一个普通响应,content type 为 text/markdown。见 PR #61800。

local 磁盘的 lazy_root_creation

Jamie York 为 local 磁盘增加 'lazy_root_creation' => true,把根目录的创建推迟到第一次写入文件时:

'disks' => [
    'local' => [
        'driver' => 'local',
        'root' => storage_path('app/private'),
        'lazy_root_creation' => true,
    ],
],

见 PR #61799。

复制全文 生成海报 Laravel PHP 框架

推荐文章

程序员茄子在线接单