如何验证上传文件数组的总大小?

How to validate the total size of an array of uploaded files?

用户正在上传多张图片,这些图片作为数组发送到 Laravel。我想验证所有合并图像的总大小。

这是我目前的规则,但我只验证单个文件是否为 1000 kB 或更小。如何检查 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'
    ];
}

你有一个包含未知数量图像的数组,你想将整个数组的大小限制为 30 MB?自定义规则应该为您执行此操作:

运行 php artisan make:rule ArraySize

然后编辑规则文件:

<?php

namespace App\Rules;

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

class ArraySize implements Rule
{
    /** @var the maximum size of the array */
    private int $size;

    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct($size)
    {
        $this->size = $size;
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $total = 0;

        if (!is_array($value)) {
            // not an array, fail it
            return false;
        }

        foreach ($value as $file) {
            if (!$file instanceof UploadedFile) {
                // not a file, fail it
                return false;
            }
            $total += $file->getSize();
        }

        return ($total / 1024) > $this->size;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return sprintf('The size of all images must be less than %d kB', $this->size);
    }
}

然后在验证中使用它:

use App\Rules\ArraySize;

...

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'              => new ArraySize(30000),
    ];
}