CakePHP 2.x 画像バリデーション

　今回はCakephp 2.xでの画像のバリデーションについてまとめようと
思います。尚、今回が初の投稿なので適宜アップデートさせていただく事がありますので
ご了承下さい。


<h1>やりたい事</h1>
1.画像のバリデーション（フォーム、画像アップロード処理の際可能）
2.画像のユニーク化（ファイル名を一意のものにする）




<h1>画像バリデーションで出来る事</h1>
•フォームでファイル形式を指定する事で意図しないファイル形式を
選択時点で除外する事が出来る。

•ファイルサイズを指定したサイズにする（最大値、最小値の指定）

•画像の拡張子の偽装チェックが出来る（悪意のあるユーザーからのアップロードを防ぐ、
セキュリティ性を高める）

<h1>1.画像のバリデーション</h1>
まずユーザー情報ページを作るという前提でテーブル構成は以下のようになります。

```PHP:table
CREATE TABLE `users` (
  `id` int(10) UNSIGNED NOT NULL,
  `username` varchar(50) DEFAULT NULL,
  `image` varchar(50) DEFAULT NULL,
  `comment` varchar(30) DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
```

次はモデルに書き加えるバリデーション

```PHP:User.php
class User extends AppModel {
	public $validate = array(
        //拡張子のチェック
		'image' => array(
			'rule1' => array(
				'rule' => array(
					'extension', array(
						'jpg',
						'jpeg',
						'gif',
						'png'
					)
				),
				'message' => '画像ではありません',
                //ファイルが空でも可
				'allowEmpty' => true
			),
            //ファイルサイズの指定
			'rule2' => array(
				'rule' => array(
					'filesize', '<=', '5000000'
				),
				'message' => '画像サイズは5MBが上限です',
			)
		),
	);
}
```

モデルでMIMEtypeを使ったバリデーションをしてもいいですが、
自分は今回編集フォームとコントローラーでチェックを行う処理
にしました。




**編集フォーム**

```PHP:edit.ctp
<?php
echo $this->Form->create('User', array('enctype' => 'multipart/form-data'));
//acceptでMIMEtype指定してあげる事により選択時点で指定外のファイルは選べなくなる、拡張子でも可能（ユーザーに優しい！）
echo $this->Form->input('User.image', array('label' => '画像アップロード', 'accept' => 'image/png, image/jpeg', 'type' => 'file'));
echo $this->Form->input('id', array('type' => 'hidden'));
echo $this->Form->end('編集する');
?>
```

**コントローラー**

```PHP:UsersController.php
public function edit($id = null) {
		if ($user['User']['id'] === $this->Auth->user('id')) {
			if ($this->request->is('submit') || $this->request->is('put')) {
                //uniqid関数でファイル名を一意なものにする
				$uniqid = uniqid(mt_rand(), true);
				$tmp_name = $this->request->data['User']['image']['tmp_name'];
				$image_name = $this->request->data['User']['image']['name'];

				if ($image_name) {
					$this->request->data['User']['image'] = $image_name;
                   //getimagesize関数で拡張子が変更されていないか判別、サイズも見れる
					if (!getimagesize($tmp_name)) {
						$this->Flash->error(__('編集されたファイルです'));
						return $this->redirect(array('action' => 'view', $id));
					}
                    //ディレクトリにファイル保存
					move_uploaded_file($tmp_name, '../webroot/img/' . $uniqid);
				} else {
					$this->User->save($this->request->data, false, array('comment', 'id'));
					$this->Flash->success(__('ユーザー情報を編集しました'));
					return $this->redirect(array('action' => 'view', $id));
				}
                //DBにも同様に保存したいので同様の文字列付与
				$this->request->data['User']['image'] = $uniqid;
                //DB保存
				if ($this->User->save($this->request->data, array('validate' => false))) {
					$this->Flash->success(__('ユーザー情報を編集しました'));
					return $this->redirect(array('action' => 'view', $id));
				}

				$this->Flash->error(__('ユーザー情報編集に失敗しました'));
				return $this->redirect(array('action' => 'view', $id));
			} else {
				$this->request->data = $this->User->findById($id);
				unset($this->request->data['User']['password']);
			}
		} else {
			$this->Flash->error(__('投稿者本人のみ編集可能です'));
			return $this->redirect(array('controller' => 'submits', 'action' => 'index', $id));
		}
	}
```

以上になります！PHPでも画像アップロードでバリデーション行いましたが、CakePHPはMVCの概念があるので勝手が違いますね！この記事ですんなりと理解出来てくれる人が一人でもいてくれたら嬉しいです！ **It’s a piece of cake!!**