消息

Laravel 13.30 中的集合 chunkBy() 和存储路径强化

发布
Laravel 13.30 图片中的集合 chunkBy() 和存储路径强化

Laravel 13.30 新增 chunkBy() 用于对相邻集合项进行分组,运行 Storage::path() 通过与其他文件系统调用相同的路径规范化器,并直接打印队列工作进程停止的原因。 queue:work 输出。

以下是本周版本的主要功能:

  • chunkBy() 关于集合和惰性集合
  • Storage::path() 现在会拒绝超出磁盘根目录的路径
  • queue:work 当工作进程退出时,写入其停止原因。
  • DevCommands::withoutVendorCommands()withoutDefaultCommands()
  • 本国的 sqlsrv: Microsoft SQL Server 的 DSN 连接字符串
  • Artisan::commandNamed() 解析一条命令,而无需构建其余部分。
  • 云队列 totalPendingSize() , totalDelayedSize() , 和 totalReservedSize()
  • route:cache 不再留下指向一次性应用程序的立面

什么是新的

chunkBy() 收藏品

chunkWhile() 该方法会在回调函数返回 false 时拆分集合,而人们在回调函数中最常编写的内容是将当前项与正在构建的块中的最后一个项进行比较:

$产品 -> chunkWhile fn ($value, $key, $chunk) => $value -> 父母 == $块 -> 最后的 () -> 父母);

chunkBy() 这种比较方式是一种方法。它接受一个键或回调函数,并在解析后的值发生变化时开始一个新的代码块:

$产品 -> '父级' (英文):
收集 ([ 1 , 1 , 2 , 2 , 1 , 1 ]) -> fn ($value) => $value);
// [[1, 1], [2, 2], [1, 1]]

钥匙穿过 data_get() 所以点表示法是可行的( chunkBy('address.city') ),并且原始密钥保留在每个数据块中。

贡献者 @约瑟夫西尔伯#61357

Storage::path() 仅限于磁盘根目录

除了一个文件系统调用之外,所有文件系统调用都会经过 Flysystem 驱动程序,该驱动程序会先规范化路径并抛出异常。 PathTraversalDetected 当它在磁盘根目录之外解析时。 Storage::path() 跳过了那一步,直接把绳子交给了 Flysystem 公司。 PathPrefixer 它除了连接字符串之外什么也不做:

贮存 :: 得到 '../../../.env' (英文): // 已拒绝
贮存 :: 小路 '../../../.env' (英文): // 在磁盘外部解析

在默认本地磁盘上, path() 返回指向应用程序的本地路径 .env 尽管 get() , delete() , 和 readStream() 所有人都拒绝了同样的论点。

无论路径源自用户输入还是其他任何来源,这一点都至关重要:

回复 () -> 下载 贮存 :: 小路 请求 -> 询问 '小路' )));

path() 现在运行该论证 WhitespacePathNormalizer 相同的归一化器 League\Flysystem\Filesystem 在添加前缀之前,会为每隔一次调用构建一个结构。相对段的解析方式取决于驱动程序的解析方式,任何逃逸出根目录的内容都会抛出异常。 PathTraversalDetected 而不是返回一个字符串。依赖于此的代码 path() 接受 .. 现在,分段操作将抛出异常。

贡献者 @KIKOmanasijev#61343

工人停止工作的原因 queue:work

退出的工作进程不会在控制台输出中留下任何退出原因的痕迹。 WorkerStopping 事件已发生 WorkerStopReason 过了一段时间,但是阅读它意味着要注册一个监听器,这对于一个你通常在观察终端或滚动日志时提出的问题来说,设置起来太麻烦了。

queue:work 现在将原因写在最后一行:

2026-09-01 13:20:40 工作进程已停止,内存限制已超出

--json 它会作为结构化记录与每个作业的输出一起输出:

{ “等级” : “警告” , “地位” : “停止” , “原因” : “记忆” , 退出代码 : 12 , "jobs_processed" : 2 , “记忆” : 1.2 , “时间戳” : “2026-09-01T13:20:40.118273+00:00” }

WorkerStopReason 枚举获得了一个 description() 用于生成人类可读字符串的方法,涵盖九种退出场景:中断、连接丢失、超出最大作业数、超出内存限制、超出最大运行时间、队列为空、队列在配置的持续时间内为空、收到重启信号以及作业超时。未写入任何内容。 --quiet 或者 --silent

贡献者 @jackbayliss#61339

选择退出供应商和默认设置 dev 命令

DevCommands 记录它所知道的一切:框架默认值( serve , queue:listen , pail (以及 Vite 脚本),任何软件包 vendor 注册表,以及应用程序自身注册的所有内容。缩小列表范围意味着要为每个你希望通过它执行的命令命名。 only() 或者说,你没有通过任何命令执行的命令 except() 第一个问题会在添加队列时出现,第二个问题会在依赖项开始注册新内容时出现。

有两种方法可以按命令来源进行过滤:

使用 照亮\基础\开发命令 ;
开发命令 :: 不含供应商命令 (); //删除供应商处已注册的所有内容/
开发命令 :: 不带默认命令 (); // 放弃框架自身的默认设置

两者都是可选的,并且不会触及应用程序注册的命令。 DevCommands 已经跟踪每个命令的来源,并按优先级(默认、供应商或用户空间)来决定在名称冲突时哪个注册胜出;这些方法都基于相同的值进行过滤。

贡献者 @jackbayliss#61344

本地 SQL Server DSN 连接字符串

Laravel 的数据库 URL 解析器假定要解析成 URL。而原生 PDO_SQLSRV 连接字符串并非 URL。

sqlsrv:Server=127.0.0.1,1433;Database=example;Encrypt=true;TrustServerCertificate=true

parse_url() Laravel 将整个路径读取后,去掉了首字母,然后返回了数据库名称。 erver=127.0.0.1,1433 结果是,连接是由一个混乱的配置建立起来的。

本国的 sqlsrv: 现在会在 URL 解析之前检测到 DSN,并将其传递给专用解析器,该解析器会提取主机、端口、数据库和支持的 PDO_SQLSRV 选项 ( Encrypt , TrustServerCertificate , MultiSubnetFailover , ApplicationIntent , LoginTimeout (以及其他部分),并将它们映射到 Laravel 的连接配置键。包含分号、右大括号或周围空格的值在重建连接字符串时会被转义。Laravel 自身的 sqlsrv://user:pass@host:port/database 该约定通过现有的 URL 解析器继续有效。

贡献者 @HenkPoley#61341

检索单个工匠指令

工匠命令会延迟执行,但如果不放弃使用名称,就无法通过名称来联系到它。 Artisan::all() 构造每个已注册的命令,以构建数组,然后您可以对数组进行索引:

// 构造每个命令。
命令 = 工匠 :: 全部 ()[ 'app:my-command' ] ?? 无效的 ;
// 仅构造已注册的 MyCommand。
命令 = 工匠 :: 命令名称 'app:my-command' (英文):

commandNamed() 该方法返回命令实例或 null

贡献者 @蒂麦克唐纳#61361

云队列总数

totalPendingSize() , totalDelayedSize() , 和 totalReservedSize() 13.27 版本新增的返回方法 0 在 SQS 上,由于 SQS 无法枚举连接使用的队列,因此无法做到这一点。而 Laravel Cloud 队列可以:它已经知道自己管理哪些队列,因此现在通过对队列求和来实现这三种方法。 managedQueues()

使用 照亮\支持\立面\云 ;
:: 队列 () -> 总预留大小 ();

之前的版本是手动构建列表的:

收集 :: 队列 () -> 托管队列 ())
-> fn 细绳 $queue) : 整数 => :: 队列 () -> 预留大小 ($队列));

贡献者 @jackbayliss#61352

其他修复和改进

  • route:cache 启动第二个一次性应用程序来收集路由的原始副本,并且引导该应用程序会将全局外观应用程序重新指向该容器。没有任何操作将其恢复,因此在运行的剩余时间内,进程中的每个外观都解析到了一个已丢弃的应用程序。 php artisan optimize 运行 route:cache 在通过以下方式注册任务之前 ServiceProvider::$optimizeCommands 一个包裹在检查路线后撞击 LogicException: Route is not bound. 该命令现在会在新应用程序启动后立即恢复外观应用程序( #61346
  • Request::clamp() 由于输入无法被限制,因此返回了 500 错误,URL 被截断。 ?per-page= 或输入为 ?per-page=foo 拒绝了该请求,而不是回退。非数值现在会使用默认值,然后由最小值和最大值对其进行限制( #61355
  • db:seed --database=mysql 切换默认连接,并在种子数据填充完成后切换回来。由于出现异常,恢复操作被跳过,导致后续所有运行的操作都指向错误的数据库。现在,该切换操作已被封装在…… try / finally#61354
  • setVisibility() 在只读取主磁盘的情况下,读取操作会返回数据。 false 对于尚未从备用方案中提升的文件,我没有做任何更改。现在问题已解决。 readerFor() 喜欢 getVisibility() , mimeType() , 和 fileSize() 已经做了( #61375
  • Queue::createPayloadUsing() 经历过 QueueManager::__call() 这会先解析默认连接,然后再进行转发。在尚未配置默认连接的应用程序的服务提供程序中注册回调函数。 The [cloud] queue connection has not been configured. 现在该方法直接在管理器上定义,因为回调是静态的,不需要连接( #61367
  • 异常页面上的工具提示渲染如下: allowHTML: false 默认情况下启用。框架自身的语法高亮源代码工具提示可通过单独的选项重新启用。 data-tippy-html-content 属性 ( #61381
  • JSON:API 资源跟踪请求中每个包含资源之间的关系,因此嵌套 include 路径解析到正确的级别,而不是从顶层请求进行预加载( #61323
  • spl_object_id() 替换 spl_object_hash() 在容器中,Eloquent 构建器、全局作用域和 Onceable 从 14.x 版本向后移植,以清除用户空间中的弃用警告( #61372
  • Handler::contextForException() 公开异常日志上下文,并且 BladeMapper::findCompiledView()detectLineNumber() 公开 #61362
  • 云事件传输返回一个布尔值。 emit()emitMany() 与其吞下失败,不如获得…… $socketFactory 用于测试的钩子,并且在异常处理程序引导期间注册,而不仅仅是在托管队列启动时注册( #61360
  • 二次通配符规则扩展修复 ValidationRuleParser::explodeWildcardRules() 已向后移植到 12.x 版本,这样可以防止在每次对大型数组进行扩展时复制累积的规则集( #61232

参考

保罗·雷德蒙德照片

Laravel News 特约撰稿人。全栈 Web 开发人员兼作家。

归档于

赞助

Laravel Cloud 标志
Laravel 云

轻松创建和管理服务器,并在几秒钟内部署 Laravel 应用程序。

访问 Laravel Cloud
Laracon 档案图像

Laracon档案

阅读文章
在 Laravel 中使用 chunkBy() 将相邻的集合项分组 图片

在 Laravel 中使用 chunkBy() 对相邻集合项进行分组

阅读文章
Laravel queue:work 现在会打印出“为什么工作进程停止”的图片

Laravel queue:work 现在会打印出工作进程停止的原因

阅读文章
Sidecar 将 Statamic 的控制面板集成到您现有的 Markdown 网站中(图片)

Sidecar 将 Statamic 的控制面板带到您现有的 Markdown 网站

阅读文章
Forte:解析和重写 Laravel Blade 模板图像

Forte:解析和重写 Laravel Blade 模板

阅读文章
组合:多列上的精妙关系图

组合:多列上的精妙关系

阅读文章