岐阜市出身のFlashエンジニア、ツチノコのブログ。ツールやTipsの紹介をメインに、Web制作の現場で役立つ情報を発信します。

ツチノコラボ

topimg

CakePHPでファイルアップロード処理を作る

2010/3/1 (月) 11:58:31

CakePHPでファイルアップロードフォームを作る機会がありましたので、記録しておきます。
ちなみにCakePHPのバージョンは1.2です。

まずはフォームを表示するビュークラスのテンプレートファイル記述から。
アップロードされたファイルを UploadsController クラスの upload メソッドで処理する想定です。

<?php
	$options = array(
		'action'=>'upload',
		'type'=>'file'
	);
	echo $form->create('Upload', $options);
?>
	<dl>
		<dt>ファイル:</dt>
		<dd><?php echo $form->file('file_name') ?>
		<?php echo $form->error('file_name') ?></dd>
	</dl>
	<?php echo $form->submit('送信'); ?>
<?php echo $form->end(); ?>

実際は付随する情報をいろいろ入力すると思いますが、分かりやすくするため最小限の構成にしています。
Formヘルパーのcreate()メソッドに渡すオプションで「”type”=>”file”」を指定すると、ファイルのアップロードに対応したHTMLタグが出力されます。(2010-03-29 加筆修正)
formヘルパーの個々のメソッドについてはここでは解説しません。

次にこのフォームからの送信情報を受け取るコントローラークラスの記述です。
以下のような条件を想定しています。

  • アップロードされたファイル名は uploads テーブルの file_name カラムに保存される
  • アップロードされたファイルの置き場所は設定ファイルに定義済み
  • マルチバイト文字が含まれるファイル名は禁止(エラーメッセージを出力)
  • ファイル名の重複を防ぐ処理を入れる

今回は省略しますが、さらに安全を期するならファイル形式のチェック機能なども必要かと。

// コントローラー定義
class UploadsController extends AppController {

	var $name = 'Uploads';
	var $uses = array('Upload');

/* 他のメンバー変数 */

/**
 * ファイルアップロードメソッド
 */
	public function upload(){
		if (!empty($this->data)) {
			if( is_uploaded_file($this->data['Upload']['file_name']['tmp_name']) ){
				if( strlen($this->data['Upload']['file_name']['name']) == mb_strlen($this->data['Upload']['file_name']['name']) ){
					//アップロードするファイルの場所
					$uploaddir = Configure::read('upload.path');
					$uploadfile = $uploaddir.DS.basename($this->data['Upload']['file_name']['name']);
					// 同じ名前のファイルがすでに存在すれば、別名に変える
					$info = pathinfo($uploadfile);
					$i = 1;
					while( file_exists($uploadfile) ){
						$i++;
						$file_name = basename($info['basename'],'.'.$info['extension']).
							'_'.$i.'.'.$info['extension'];
						$uploadfile = $info['dirname'].DS.$file_name;
						$this->log('アップロードファイル名を再作成:'.$uploadfile, LOG_DEBUG);
						$this->data['Upload']['file_name']['name'] = $file_name;
					}
					//画像をテンポラリーの場所から、正式な置き場所へ移動
					if (move_uploaded_file($this->data['Upload']['file_name']['tmp_name'], $uploadfile)){
						chmod($uploadfile, 0666);
						$this->Upload->create();
						// DBにレコード登録
						$this->data['file_name'] => $data[$this->name]['file_name']['name'];
						if( $this->Upload->save($this->data) ){
							//成功
							$this->Session->setFlash("ファイルのアップロードに成功しました。");
						} else {
							//失敗
							$this->Session->setFlash("データベースの登録に失敗しました。");
						}
					} else {
						//失敗
						$this->Session->setFlash("ファイルのアップロードに失敗しました。");
					}
				}else{
					$this->Upload->invalidate("file_name","ファイル名に全角文字は使用できません。");
				}
			} else {
				$this->Upload->invalidate("file_name","ファイルをアップロードしてください。");
			}
		}
	}

/* 他のメソッド */

}

とりあえずこれで最小限の構成でしょうか。
本当は付随する情報も含めた保存データを処理するために、モデルクラスにも独自メソッドを用意したりしていますが、そこは皆さんの創意工夫でお願いします・・・。

  • カテゴリ : Webプログラミング
  • タグ:

コメント

コメント/トラックバックはまだありません

トラックバック

コメントをどうぞ

�u���O