Laravel 文件数组总大小验证:自定义规则实现

碧海醫心
发布: 2025-12-02 12:06:26
原创
880人浏览过

Laravel 文件数组总大小验证:自定义规则实现

本教程详细介绍了如何在 laravel 中验证上传文件数组的总大小。由于 laravel 内置验证器主要针对单个文件大小,对于整个文件数组的合计大小验证,需要通过创建自定义验证规则来实现。文章将指导您完成自定义规则的创建、逻辑实现,并将其集成到表单请求的验证规则中,确保所有上传文件的总大小符合预期限制。

在 Laravel 应用中处理文件上传时,我们经常需要对单个文件的大小、类型等进行验证。然而,当用户上传多个文件(作为文件数组)时,有时不仅需要限制每个文件的大小,还需要限制所有文件合计的总大小。Laravel 的内置验证规则,例如 max,通常只作用于单个文件,无法直接验证文件数组的聚合大小。本文将指导您如何通过创建自定义验证规则来解决这一问题。

1. 理解 Laravel 内置文件验证的局限性

考虑以下典型的 Laravel 验证规则,它限制了每个 images 数组中的图片文件类型和最大大小(1000 KB):

public function rules()
{
    return [
        // ... 其他验证规则
        'images.*' => 'mimes:jpg,jpeg,png|max:1000' // 验证每个图片文件不超过 1000 KB
    ];
}
登录后复制

这里的 images.* 规则确保了数组中的每个文件都符合要求。但如果用户上传了 10 张图片,每张 900 KB,那么总大小将达到 9000 KB (9 MB),这可能仍然超出了我们对整个上传批次的总大小限制。为了实现对总大小的验证,我们需要一个自定义的解决方案。

2. 创建自定义验证规则

Laravel 提供了强大的自定义验证规则机制,允许我们定义复杂的验证逻辑。我们将创建一个名为 ArraySize 的自定义规则来验证文件数组的总大小。

首先,使用 Artisan 命令生成一个新的验证规则:

php artisan make:rule ArraySize
登录后复制

这会在 app/Rules 目录下创建一个 ArraySize.php 文件。

3. 实现自定义规则逻辑

打开 app/Rules/ArraySize.php 文件,并根据以下示例代码修改其内容。这个规则的核心逻辑是遍历文件数组,累加每个文件的大小,然后将总大小与我们设定的最大值进行比较。

腾讯Effidit
腾讯Effidit

腾讯AI Lab开发的AI写作助手,提升写作者的写作效率和创作体验

腾讯Effidit 65
查看详情 腾讯Effidit
<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Http\UploadedFile;

class ArraySize implements Rule
{
    /**
     * 允许的文件数组最大总大小,单位为 KB。
     *
     * @var int
     */
    private int $maxSize;

    /**
     * 创建一个新的规则实例。
     *
     * @param int $maxSize 允许的最大总大小(KB)
     * @return void
     */
    public function __construct(int $maxSize)
    {
        $this->maxSize = $maxSize;
    }

    /**
     * 判断验证规则是否通过。
     *
     * @param  string  $attribute 字段名称
     * @param  mixed  $value     待验证的值 (文件数组)
     * @return bool
     */
    public function passes($attribute, $value): bool
    {
        $totalSize = 0;

        // 确保 $value 是一个数组
        if (!is_array($value)) {
            return false;
        }

        foreach ($value as $file) {
            // 确保数组中的每个元素都是 UploadedFile 实例
            if (!$file instanceof UploadedFile) {
                return false;
            }
            $totalSize += $file->getSize(); // getSize() 返回字节数
        }

        // 将总字节数转换为 KB,并判断是否小于允许的最大值
        // 如果总大小小于最大允许值,则验证通过 (返回 true)
        return ($totalSize / 1024) < $this->maxSize;
    }

    /**
     * 获取验证失败时返回的错误消息。
     *
     * @return string
     */
    public function message(): string
    {
        return sprintf('所有图片的总大小必须小于 %d KB。', $this->maxSize);
    }
}
登录后复制

代码解析:

  • __construct(int $maxSize): 构造函数接收一个 $maxSize 参数,用于设定允许的最大总大小,单位为 KB。
  • passes($attribute, $value):
    • 初始化 $totalSize 为 0,用于累加文件大小。
    • 首先检查 $value 是否为数组,如果不是,则验证失败。
    • 遍历 $value 数组,对每个元素:
      • 检查它是否是 Illuminate\Http\UploadedFile 的实例。这确保我们处理的是实际上传的文件对象。
      • 通过 $file->getSize() 获取当前文件的大小(单位为字节),并累加到 $totalSize。
    • 最后,将 $totalSize(字节)转换为 KB ($totalSize / 1024),并与构造函数中传入的 $maxSize 进行比较。如果总大小小于 $maxSize,则 passes 方法返回 true(验证通过),否则返回 false(验证失败)。
  • message(): 定义了当验证失败时返回的错误消息。使用 sprintf 可以动态地将 $maxSize 插入到消息中,提供更具体的信息。

4. 在验证中使用自定义规则

现在,您可以在您的表单请求(Form Request)或控制器中引入并使用这个自定义规则。

首先,在文件顶部引入 ArraySize 规则:

use App\Rules\ArraySize;
登录后复制

然后,在您的 rules() 方法中,将 ArraySize 规则应用于 images 字段。请注意,images 字段代表整个文件数组,而 images.* 字段则代表数组中的每个单独文件。

public function rules()
{
    return [
        'title'               => 'required|max:125',
        'quantity'            => 'required|numeric|min:0',
        'retail_price'        => 'required|numeric|min:0',
        'diamond_shape_id'    => 'required',
        'diamond_cut_id'      => 'required',
        'diamond_color_id'    => 'required',
        'diamond_clarity_id'  => 'required',
        'carat_weight'        => 'required',
        'diamond_polish_id'   => 'required',
        'diamond_symmetry_id' => 'required',
        'video_url'           => ['url', new EmbeddableUrl],
        'images.*'            => 'mimes:jpg,jpeg,png|max:1000', // 验证单个文件
        'images'              => ['required', new ArraySize(30000)], // 验证文件数组总大小,30000 KB = 30 MB
    ];
}
登录后复制

在上述示例中,new ArraySize(30000) 表示我们希望所有上传图片的合计大小不得超过 30000 KB (即 30 MB)。同时,images.* 规则仍然会验证每个单独的文件不超过 1000 KB。

5. 注意事项与最佳实践

  • 单位一致性:在 ArraySize 规则中,$maxSize 参数的单位是 KB。确保在实例化规则时传入的值是正确的 KB 单位。
  • 错误消息本地化:如果您的应用支持多语言,您可以通过在 resources/lang/{locale}/validation.php 文件中添加自定义消息,或者在规则的 message() 方法中返回 __('validation.custom.images.array_size') 来实现错误消息的本地化。
  • 与其他规则结合:将 images.* (针对单个文件) 和 images (针对文件数组) 的验证规则结合使用,可以提供更全面的验证。
  • 性能考量:对于非常大的文件数组或文件,计算总大小可能会消耗一些时间。在极端情况下,可以考虑在文件上传前进行前端预校验,以减少不必要的服务器请求。
  • 空数组处理:在上述 rules() 中,我们为 images 字段添加了 required 规则。这意味着如果 images 数组为空,它将首先被 required 规则捕获。如果您允许空数组,但仍然想验证非空数组的总大小,可以移除 required 规则。

总结

通过创建自定义验证规则,我们成功解决了 Laravel 中对上传文件数组总大小进行验证的需求。这种方法不仅功能强大,而且高度可定制,能够适应各种复杂的业务逻辑。掌握自定义验证规则的技巧,将大大提升您在 Laravel 中处理复杂数据验证的能力。

以上就是Laravel 文件数组总大小验证:自定义规则实现的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号