laravel5.2 画像アップロードで紆余曲折

qiita.com

よっしゃ!これくらい書いてやろう!こないだカスタムバリデーション覚えたしね! と思ってたらいろいろ詰んだ。

フォーム

<form enctype="multipart/form-data" method="post" action="/photo/set">
    {{ csrf_field() }}
    <input type="hidden" name="MAX_FILE_SIZE" value="51200" />
    <input type="file" name="photo" />
    <p>
        <input type="submit" class="" value="登録する" />
    </p>
</form>

これの

<input type="hidden" name="MAX_FILE_SIZE" value="51200" />

が反応して、50KB以上のデータを送ろうとするとエラーになる、ってのはいいんです。 通常のPHPならば

$_FILES['upfile']['error'] == UPLOAD_ERR_FORM_SIZE

とかでチェックできるんだろうし、CSRFチェックしてるとはいえ偽装されたりしてもいやだから

$_FILES['upfile']['size']

とかでチェックする。

なぜかカスタムバリデーターに来ない

カスタムバリデータでチェックしてやるぜー!と思ってたら、なぜかそこまでたどり着きません。 正常パターンはカスタムバリデータに届くのに。

なんでだろうとRequest クラスとか追っかけたんですけど、途中でめまいがしてやめました。

って事は バリデーションルールのrequiedでチェックできるんじゃ?

できた。

ってかそもそも定義されているルールで判別できちゃうんじゃ?

    public function rules()
    {
        return [
            'photo' => 'required|image|mimes:jpeg|max:50',
        ];
    }

できた。

画像受け取ってリサイズ

コントローラのPOSTで呼ばれるメソッド

<?php
public function photoSet(ImageRequest $request)
{

    // 画像リサイズ、移動処理
    $result = UploadImage::upload($request->file('photo')->getPathname());
    if (!$result) {
        // 小さいエラー
        $error = ['画像が小さすぎます'];
        return redirect('/photo')
            ->withErrors($error)
            ->withInput();
    }
    $request->session()->flash('flash_message', '登録しました。');
    return redirect('/photo');
}

共通関数的に作った画像ごにょごにょする UploadImage クラスの upload メソッド

縦横100px以上指定。大きい方の辺が480pxこえたらアスペクト比を維持して縮小。

<?php

// 画像最大値/最小値
const max_size = 480;
const min_size = 100;

public static function upload($temp_filename)
{
    // サイズチェック
    $image = Image::make($temp_filename);
    $width = $image->width();
    $height = $image->height();

    if ($width < self::min_size || $height < self::min_size) {
        return false;
    }

    // ファイル名決定
    $filepath = public_path() . '/assets/upload/';
    $filename = (string)time() . '.jpg';
    $fullpath = $filepath . $filename;

    // リサイズ
    $new_width = null;
    $new_height = null;

    if ($width > $height) {
        if ($width > self::max_size) {
            $new_width = self::max_size;
        }
    } else {
        if ($height > self::max_size) {
            $new_height = self::max_size;
        }
    }

    if (!is_null($new_width) || !is_null($new_height)) {
        $image->resize($new_width, $new_height, function ($constraint) {
            $constraint->aspectRatio();
        });
    }

    // 保存
    $image->save($fullpath);

    return true;
}

Image:: は Intervention Image ってやつ。

インストール

qiita.com

メソッドとか

Intervention Image - Introduction