Laravel を使用して画像または動画としてアップロードを検証する


Laravel の Validator を使用すると、'image' ルールを使用して、リクエストのファイル フィールドを画像として簡単に検証できます.また、MIME タイプを制限することで、ビデオを検証するためのルールをまとめてハックできます.

$request->validate([
    'image_upload' => 'image|max:1024',
    'video_upload' => 'mimetypes:video/avi,video/mpeg,video/quicktime|max:102400'
]);


しかし、最大 10 メガバイトのビデオまたは 1 メガバイト以下の画像を受け入れる単一の upload フィールドがある場合はどうなるでしょうか?これは、Laravel の Validator では非常に厄介です.Laravel の組み込みの検証ルールを使用したエレガントなソリューションはないようです.

ありがたいことに、Laravel では独自のカスタム検証ルールを作成できます.アップロードが画像か動画かを確認し、アップロードの種類に基づいてルールを検証する a custom rule closure を作成できます.

$request->validate([
    'file', // Confirm the upload is a file before checking its type.
    function ($attribute, $value, $fail) {
        $is_image = Validator::make(
            ['upload' => $value],
            ['upload' => 'image']
        )->passes();

        $is_video = Validator::make(
            ['upload' => $value],
            ['upload' => 'mimetypes:video/avi,video/mpeg,video/quicktime']
        )->passes();

        if (!$is_video && !$is_image) {
            $fail(':attribute must be image or video.');
        }

        if ($is_video) {
            $validator = Validator::make(
                ['video' => $value],
                ['video' => "max:102400"]
            );
            if ($validator->fails()) {
                $fail(":attribute must be 10 megabytes or less.");
            }
        }

        if ($is_image) {
            $validator = Validator::make(
                ['image' => $value],
                ['image' => "max:1024"]
            );
            if ($validator->fails()) {
                $fail(":attribute must be one megabyte or less.");
            }
        }
    }
]);


最初に認めておきたいのは、このコードはかなり洗練されていないように見えるということです.しかし、それは機能し、クロージャーは 'image''max' などの既存の Validator ルールを活用します.

よりオブジェクト指向のアプローチを好む場合は、このコードを Custom Rule Object に抽出し、 is_video() および is_image() のメソッドを抽出することもできます. Rule オブジェクトのコンストラクターで最大アップロード サイズを構成可能にすることもできます.限界はありません.

うまくいけば、この投稿が、あなた自身のプロジェクトの 1 つでこの特定の課題に出くわした場合に、時間を節約できることを願っています.また、これを達成するためのよりエレガントな方法を知っている場合は、コメントを残してください!