アップロードファイルのバリデーションルール

CakePHP 2.2や2.3になってファイルアップロードに対するルールがコアバリデーションに追加されているようで、まとめてみました。

コアバリデーション

関連しそうなルールは以下の4つのようです。
fileSize - ファイルサイズについて
mimeType - MIMEタイプについて
uploadError - ファイルアップロードのエラー有無について
extension - 拡張子について

ファイルアップロードフォームから受け取るデータ配列

簡単なフォームの例

<?php 
echo $this->Form->create( 'File', array( 'type'=>'> file', 'enctype' => 'multipart/form-data', 'url'=>'/upload/'));
    echo $this->Form->input( 'image', array( 'type' => 'file'));
    echo $this->Form->submit( __('Upload'));
echo $this->Form->end(); 
?>

上記のフォームから受け取るこんな感じだと思います。

    [File] => Array
        (
            [image] => Array
                (
                    [name] => 5231ddd0ccdbf_thumb.jpg
                    [type] => image/jpeg
                    [tmp_name] => /var/tmp/phpCN8Bo8
                    [error] => 0
                    [size] => 4613
                )

        )

バリデーションルールを設定

配列がネストしているのでバリデーションルールもネストする必要があるのかなと思ったのですが、Cake側でやってくれるようで、そのまま定義すればいいようです。
ポイントは、「uploadError」ルールを先頭にもってくることでしょうか? ファイル未選択で空の場合にはここではじかないと、その他のルールを実行しようとしてエラーが発生してしまいます。

// モデル:File.php
public $validate = array(
    'image' => array(

        // ルール:uploadError => errorを検証 (2.2 以降)
        'upload-file' => array( 
            'rule' => array( 'uploadError'),
            'message' => array( 'Error uploading file')
        ),

        // ルール:extension => pathinfoを使用して拡張子を検証
        'extension' => array(
            'rule' => array( 'extension', array( 
                'jpg', 'jpeg', 'png', 'gif')  // 拡張子を配列で定義
            ),
            'message' => array( 'file extension error')
        ),

        // ルール:mimeType => 
        // finfo_file(もしくは、mime_content_type)でファイルのmimeを検証 (2.2 以降)
        // 2.5 以降 - MIMEタイプを正規表現(文字列)で設定可能に
        'mimetype' => array( 
            'rule' => array( 'mimeType', array( 
                'image/jpeg', 'image/png', 'image/gif')  // MIMEタイプを配列で定義
            ),
            'message' => array( 'MIME type error')
        ),

        // ルール:fileSize => filesizeでファイルサイズを検証(2GBまで)  (2.3 以降)
        'size' => array(
            'maxFileSize' => array( 
                'rule' => array( 'fileSize', '<=', '10MB'),  // 10M以下
                'message' => array( 'file size error')
            ),
            'minFileSize' => array( 
                'rule' => array( 'fileSize', '>',  0),    // 0バイトより大
                'message' => array( 'file size error')
            ),
        ),
    ),
);

ファイル名の長さを検証するケースはあまり無いと思いますが、自作する必要があるようですね。(存在してたらすいません)

処理の流れの注意点

通常の流れは、「ファイルアップロード」→「バリデーション」→「ファイル移動(move_uploaded_file)」→「ファイル情報save」のような感じになると思います。

mimeTypeのバリデーション処理では、tmp_nameにあるファイルからmime情報を取得してバリデーションを行うため、save時は、'validate' => falseを付与して、バリデーション処理をスキップさせて下さい。(コントローラ内でバリデーション処理を呼び出す)
そうしないと既に移動されて存在しないファイルに対してバリデーション処理をおこなうためエラー("Can not determine the mimetype.")となってしまいます。

// バリデーション
$this->File->set( $this->request->data );
if ($this->File->validates( array( 'fieldList' => array( 'image')))) {
    // ファイル移動
    if( move_uploaded_file( $this->request->data['File']['image']['tmp_name'], IMAGES . 「ファイルパス」) ){
        // save
        if( $this->File->save( $this->request->data, array( 'validate' => false)) ) {
        } else {
            // saveエラーの場合
        }
    } else {
        // ファイル移動エラーの場合
    }
} else {
    // バリデーションNGの場合
}

(ファイル情報saveしてからファイル移動(move_uploaded_file)であれば、問題ないと思いますが。)

Validationユーティリティ:/lib/Cake/Utility/Validation.php
Models > Data Validation
  • このエントリーをはてなブックマークに追加

関連記事

(メール・URL・電話・郵便・IP) データ バリデーション

今回は、プロフィール情報に使用されるデータに絞ったバリデーションルールです。 バリデーションルール 以下の5つのバリデーションルールがコアに用意されています。 email メールアドレス

多言語サイト向けに翻訳ファイルを使って翻訳を行う

CakePHPには、翻訳をビヘイビアを使用する方法と翻訳ファイルを使用する方法の2つがあるそうです。(他にもあるのかな?) 今回は、翻訳ファイルを使用して言語の切り替えを行い、その言語設定をCook

バリデーション前後に処理を追加できる「beforeValidate」「afterValidate」

CakePHPでは、「beforeValidate」「afterValidate」というバリデーション処理の前後で追加の処理を実装できるコールバック関数が用意されています。 beforeVali

ユーザ登録(仮登録・メール・本登録)

以前1.3版で投稿した「ユーザ登録」処理の2.x版を作成しました。フローは同じで以下のようにします。 1. メールアドレス・パスワードでユーザ登録 2. この時点では仮登録として、本登録用のU

hasOne アソシエーション

hasOneアソシエーションはテーブル間で1つのレコードに対して他のテーブルに紐付くレコードが1つの場合にjoinする場合に使用します。 CakePHPのドキュメントにならってUserモデルとP

CakeEmailでメール送信(@gmail)

CakePHP 2になって追加されたクラスCakeEmailがシンプルに使えます。これを使用してメール送信を行う処理を実装してみました。 CakeEmailクラスの読み込み /app/Config

パス定数と変更方法やURLの取得

CakePHPは基本的にはディレクトリそのまま配置することで構築が可能ではありますが、設定パスを変更することでセキュリティに考慮した構成にすることや運用性をもたせたものにすることが可能になります。

recursive設定によるfind()性能改善

CakePHPでは、モデルにアソシエーションを設定している場合、recursive(=>joinする階層)はデフォルトで0に設定されています。「recursiveゼロ」の意味するところとは、「1跨ぎま

日付・時間のバリデーション

日付や時刻に関するバリデーションは以下のルールがビルトインされています。 date 日付 time 時刻 datetime 日時 (m:「月」を数字表記 / M:「月」を英語表記)

Markdown Plugin

「Markdown CakePHP Plugin」は、MarkDown書式をレンダリングしてくれるビューヘルパーです。MarkDownについて勉強しているうちに出会ったので試し打ちです。 ダウンロー

Comment

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

PAGE TOP ↑