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

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)であれば、問題ないと思いますが。)
Models > Data Validation
関連記事
-
-
Syslogログエンジン
2.4から「Syslog」ログクラスが追加され、簡単にSyslogを使用できるようになりました。 CakePHP側の設定はbootstrap.php内のCakeLogコンフィグのengineを'Sy
-
-
Jsヘルパーを使用してAjax更新
更新処理でページ遷移を伴う場合、ページ全体をレスポンスするのに対して、Ajax処理ではページの一部のレスポンスが可能となるためサーバからの通信量を抑えることが可能となります。デモ head
-
-
バリデーション前後に処理を追加できる「beforeValidate」「afterValidate」
CakePHPでは、「beforeValidate」「afterValidate」というバリデーション処理の前後で追加の処理を実装できるコールバック関数が用意されています。 beforeVali
-
-
パス定数と変更方法やURLの取得
CakePHPは基本的にはディレクトリそのまま配置することで構築が可能ではありますが、設定パスを変更することでセキュリティに考慮した構成にすることや運用性をもたせたものにすることが可能になります。
-
-
多言語サイト向けに翻訳ファイルを使って翻訳を行う
CakePHPには、翻訳をビヘイビアを使用する方法と翻訳ファイルを使用する方法の2つがあるそうです。(他にもあるのかな?) 今回は、翻訳ファイルを使用して言語の切り替えを行い、その言語設定をCook
-
-
日付・時間のバリデーション
日付や時刻に関するバリデーションは以下のルールがビルトインされています。 date 日付 time 時刻 datetime 日時 (m:「月」を数字表記 / M:「月」を英語表記)
-
-
CakeEmailでメール送信(@gmail)
CakePHP 2になって追加されたクラスCakeEmailがシンプルに使えます。これを使用してメール送信を行う処理を実装してみました。 CakeEmailクラスの読み込み /app/Config
-
-
hasOne アソシエーション
hasOneアソシエーションはテーブル間で1つのレコードに対して他のテーブルに紐付くレコードが1つの場合にjoinする場合に使用します。 CakePHPのドキュメントにならってUserモデルとP
-
-
コントローラ内でバリデーション処理を呼び出す
CakePHPでは、saveメソッドの際にバリデーション処理も自動で行われますが、save処理と切り離してバリデーションを行うこともできます。このときは、save時と若干異なる処理体系になります。
-
-
数値系バリデーション
CakePHP 2になっていくつか数値用バリデーションルールが追加されています。 数値用 (コア)バリデーション decimal - 十進数であること numeric - 数値であること
Comment
なるー
[…] http://kwski.net/cakephp-2-x/1152/ […]
[…] http://kwski.net/cakephp-2-x/1152/ […]
アップロードファイルのバリデーションルール #CakePHP #trick876 #validation
http://t.co/1kGisLqpp7