cakePHP2.1でファイルのアップロードとダウンロード

cakePHP2.1の
ファイルアップロード
ファイルダウンロード
をやってみようと思います。ひとまずファイルアップロード用にテーブル作成します。
今回は、ファイルの実体は特定のディレクトリに保存するので、ファイルの実体はDBには保存しません。


mysql> desc upload_files;
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | | NULL | |
| name | varchar(50) | NO | | NULL | |
| file_name | varchar(100) | NO | | NULL | |
| extension | varchar(10) | NO | | NULL | |
| size | int(11) | NO | | 0 | |
| download_count | int(11) | NO | | 0 | |
| created | datetime | YES | | NULL | |
| deleted | tinyint(1) | YES | | 0 | |
| deleted_date | datetime | YES | | NULL | |
+----------------+--------------+------+-----+---------+----------------+

次にファイルアップロード用のViewです。
Viewにはこんな感じでアップロードフォームを作ります。

echo $this->Form->create(null, array('action' => 'index', 'enctype' => 'multipart/form-data'));
echo $this->Form->input(null, array('type'=>'file','label'=>'対象ファイル' ));
echo $this->Form->submit('ファイルアップロード');

次はアップロード用のコントローラー。index()メソッドです。一覧とアップロードされた
ページを一緒にしているので一覧もとりに行っています。
定数化したり、モデルに処理を移動する必要があったりしますが、まずはこれで。

public function index() {
	$this->UploadFile->recursive = 0;
	$this->set('uploadFiles', $this->paginate());
	if(!empty($this->request->data)){
		$uploaddir = self::FILE_SAVE_PATH.DS;//事前にパスを宣言して、パーミッション変えておいてください。
		$uploadfile = $uploaddir . date("YmdHis");
		$this->request->data['UploadFile']['user_id']	 = $this->Auth->User('id');
		$this->request->data['UploadFile']['file_name'] = self::FILE_SAVE_PATH.DS.basename($uploadfile);
		$this->request->data['UploadFile']['extension'] = pathinfo($this->request->data['UploadFile']['name'],PATHINFO_EXTENSION);
		if(!move_uploaded_file($this->request->data['UploadFile']['tmp_name'], $uploadfile)){
			return;
		}
		if($this->request->data['UploadFile']['size'] > 1000000){
			$this->UploadFile->invalidate('name','ファイルサイズが大きすぎます');
			return;
		}
		if($this->UploadFile->save($this->request->data)){
			$this->Session->setFlash('アップロードを完了しました', true);
		}else{
			$this->Session->setFlash('アップロードに失敗しました', true);
		}
		$this->redirect('index');
	}
}

さて次は一覧のViewです。ダウンロードリンクですな。

echo $this->Html->link($uploadFile['UploadFile']['name'], array('controller' => 'upload_files', 'action' => 'download', $uploadFile['UploadFile']['id'])); 

それでは、ダウンロード用のメソッドを見ていきます。ここでポイントは、MediaViewを使うとすんごい便利なんです。
ダウンロードは断然、cakePHPのコアのMediaViewを使うとダウンロードが簡単にできるのでおすすめ。
1.3では「$this->view = ‘Media’;」という使い方だったのですが、(2.0はわからない・・・)2.1では
「$this->viewClass = ‘Media’;」という利用方法に変わっている、というのが本日の重要ポイントです。
lib/Cake/View にあるMediaView.phpをみると利用方法が書いて有ります。
ヘッダーの書き出しとか自前でしなくてよくて、このMediaViewが勝手に判断してくれるのでかなり便利です。
これで、ダウンロードリンクをクリックしてもページ遷移なしでファイルがダウンロードできます。お便利。
本当はダウンロードされるたびにカウントアップしたものにしようと思っていますが・・今回はとりあえずスルーしました。

public function download($id) {
	$this->viewClass = 'Media';
	$this->UploadFile->id = $id;
	$this->UploadFile->recursive = -1;
	$data = $this->UploadFile->read();
	$params = array(
		'id'=>basename($data['UploadFile']['file_name']),
		'name'=>preg_replace("/.[^.]+$/","",$data['UploadFile']['name']),
		'download'=>true,
		'extension'=>$data['UploadFile']['extension'],
		'path'=>dirname($data['UploadFile']['file_name']).DS
	);
	$this->set($params);
}

月末に怒涛のブログ記事を書きましたが、まだまだ2.1関連の内容をお届けできればと思います!

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中