CakePHP 2.3でファイルのアップロード処理を作る
2017/04/29
CakePHPでファイルアップロードを作る
ファイルアップロードの参考サイト
CakePHP 2.3でプログラム開発を行っていますが、ファイルのアップロード処理についてググっていたら、下記のサイトに行き当りました。
ほほー。ファイルアップロードにも Pluginがあるのか、と思ったものの、このページではプラグインに頼らない、と書いてありましたので、私も頼らずに実際に作ってみることにしました。(記事が書かれたのが 2011年2月ですので、その後のバージョンアップなどでどうなったかは分かりませんが。)
http://lambdagroove.blogspot.jp/2011/02/cakephp.html
簡単なファイルのアップロードであれば下記のページに従って作っていけば、簡単に出来上がります。
http://www.almondlab.jp/labs/1043
上記の方法では、実運用に際してファイルの削除処理などが必要になってくると思います。
また、ファイルの管理を煩雑にしないために、画像などのファイル情報を DBに保存したい、という場合もあるかと思います。
その場合は、下記のページが参考になりました。
http://c-brains.jp/blog/wsg/10/06/05-074544.php
ですが、このページの通りに作っていくと、「Viewファイルの記述がおかしい」というエラーになってしまいましたので、その前に作った簡易フォームのスクリプトを借りることにしました。
(CakePHP 2.0では echoのエイリアスである e()が使えなくなっていますので、そのほかの不具合もバージョンの違いによるものと思われます。)
CakePHPでファイルアップロードのサンプルコード
また、ファイルが jpeg固定でしたので、それを可変にし、ついでに元ファイルのファイル名、ファイルサイズといった情報も取得するために、テーブルを拡張したり、そのままではうまく画像が呼び出せなかったために、画像の確認するためのファイルなどを作りましたので、あわせてそちらも紹介いたします。
————–(テーブル)
1 2 3 4 5 6 7 8 9 |
CREATE TABLE `images` ( `id` int(11) NOT NULL AUTO_INCREMENT, `filename` varchar(60) NOT NULL, `contents` mediumblob NOT NULL, `moto_filename` text NOT NULL, `filetype` text NOT NULL, `filesize` int(11) NOT NULL, PRIMARY KEY (`id`) ); |
————–
————–(/View/Images/index.ctp)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<div class="images form"> <?php echo $this->Form->create('Image', array('action' => 'add', 'type' => 'file')); ?><fieldset> <legend><?php echo __('Add Image'); ?></legend> <?php echo $this->Form->file('image'); ?> </fieldset> <?php echo $this->Form->end(__('画像を追加'));?> </div><!-- form --> <div class="uploads index"> <h2><?php echo __('Images'); ?></h2> <table cellpadding="0" cellspacing="0"> <tr> <th><?php echo __('id'); ?></th> <th><?php echo __('file_name'); ?></th> <th><?php echo __('contents'); ?></th> </tr> <?php foreach ($images as $image) : ?> <tr> <td><?php echo h($image['Image']['id']); ?></td> <td><?php echo h($image['Image']['filename']); ?></td> <td><?php echo $this -> Html->link(__("/images/contents/{$image['Image']['filename']}"), array('action' => "/contents/{$image['Image']['filename']}" ), array ( 'target' => '_blank' ) ); ?></td> </tr> <?php endforeach; ?> </table> </div><!-- index --> |
————–
/View/Images/contents.ctp は、ないとエラーになりますので作成する必要がありますが、中身は空のファイルになります。
————–(/View/Images/contents.ctp)
————–
/Controller/ImagesController.php は、以下のようになります。
それぞれの処理の解説は、参考にしたバシャログさんのサイトを見ていただく方が分かりいいかと思います。
————–(/Controller/ImagesController.php)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
<?php class ImagesController extends AppController { public $helpers = array ( 'Html', 'Form', 'Session' ); public $components = array ( 'Session' ); var $uses = array('Image'); function index(){ $images = $this->Image->find('all'); $this->set(compact('images')); } /** * 画像を登録する */ function add(){ $limit = 1024 * 1024; debug($this->data); // 画像の容量チェック if ($this->data['Image']['image']['size'] > $limit){ $this->Session->setFlash('1MB以内の画像が登録可能です。'); $this->redirect('index'); } // アップロードされた画像か if (!is_uploaded_file($this->data['Image']['image']['tmp_name'])){ $this->Session->setFlash('アップロードされた画像ではありません。'); $this->redirect('index'); } // 保存 $image = array( 'Image' => array( 'filename' => md5(microtime()) . '.' . $extension = end(explode('.', $this->data['Image']['image']['name'])), 'contents' => file_get_contents($this->data['Image']['image']['tmp_name']), 'moto_filename' => $this->data['Image']['image']['name'], 'filetype' => $this->data['Image']['image']['type'], 'filesize' => $this->data['Image']['image']['size'], ) ); $this->Image->save($image); $this->Session->setFlash('画像をアップロードしました。'); $this->redirect('index'); } function contents($filename) { $this->layout = false; $image = $this->Image->findByFilename($filename); if (empty($image)) { $this->cakeError('error404'); } header('Content-type: ' . $image['Image']['filetype'] ); echo $image['Image']['contents']; } } |
————–
MIMEタイプの追加について
また、今回追加した MIMEタイプなどの情報は、下記サイトを参考にして作成しました。
http://vitafacio.sakura.ne.jp/wordpress/?p=35
ファイルアップロードの表示側の処理
また、http://localhost/cake/images/contents/xxxxxxxx.jpg のような形式では文字化けしたような文字が表示され、なぜかうまく表示されずさんざん悩んだのですが、それを改善させる方法を見つけることはできませんでした。
PDFや、csvファイルは問題なく表示されますが、jpeg、gifなどの画像ファイルが正しく表示されないという不具合でしたので、おそらく「header(‘Content-type:…….」の出力部分がうまく処理されていないのだろうと思うのですが...
ただ、実際の使用方法に近い記述の方法で確認したところ、正しく表示されましたので、それで良しとしたところもあります。
————–(/webroot/test.php)
1 |
<img src="./images/contents/xxxxxxxx.jpg"> |
————–
上記のファイルを作成し、webrootにおいてアクセスすると画像ファイルも無事に表示されましたので、画像も正しくアップロードされていることが確認できました。
ファイル名を乱数にしてセキュリティを向上させる方法
ファイル名を乱数や、指定の値に変更し、セキュリティを向上させる方法も書いていますので、こちらも参考にしてください。
CakePHP 2.3でファイルをアップロード・その2 ファイル名を乱数で設定
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
-
CakePHP4でロギングスコープやログレベルを使用してログを出し分ける方法を解説
CakePHPのログ出力方法の解説。app.phpにログ設定をし、スコープやレベルを指定してログ出力を振り分ける方法、CakePHP4で配列出力にはvar_exportが必要なことなどを解説。
-
-
CakePHP4で現在処理しているコントローラー名、アクション名を取得する方法
CakePHP3で現在処理しているコントローラー名、アクション名を取得する方法を解説。複数の方法があるが、getParam()メソッドを使う方法が汎用性があって便利かも。
-
-
CakePHP3の検索プラグイン「friendsofcake/search」の様々な検索の仕方の実装方法
CakePHP3で検索をするプラグイン「friendsofcake/search」の検索条件のカスタマイズ方法の解説。検索項目を増やしたり、以上、以下での検索や、チェックボックスによる検索の方法などを解説。
-
-
CakePHP3のユーザ管理・ログイン認証プラグインCakeDC/Usersのインストール解説・3.6以降対応
CakePHP3のユーザ管理プラグイン Usersは、ユーザ登録、メール認証、ログイン認証、ユーザ管理、権限管理、reCAPTCHAなど会員制のサイトを簡単に実現可能。その導入方法、カスタマイズ方法を解説。
-
-
CakePHP4のFrozenDateで1ヵ月前、先月、今月1日、来月末の日付などを算出する方法
CakePHPには「FrozenDate」の日付を扱う関数が用意されている。これを利用して、1ヶ月後、月末日、月初日、5日後などを指定して日付を取得できる。それを解説。
-
-
CakePHP3のCakeDC/Usersのログイン後のリダイレクトとユーザ権限管理の設定解説
CakeDC謹製Usersプラグインの紹介。ログイン認証後にリダイレクトする先の設定方法についての解説と実運用するために必要なコツを解説。便利な仕組みも仕様の理解があって初めてうまく使いこなせる。
-
-
CakePHP 2.3 ログイン、操作履歴、アクセスログ出力
CakePHPでログインや操作履歴などのアクセスログ出力処理を作成します。
-
-
VirtualBoxにCakePHP3を設置。必要なCentOS、Apache、PHP、MySQL、Composerをインストールし設定する
VirtualBoxにCentOS、Apache、MySQL、PHPをインストールするところから初めてCakePHP3の開発環境を構築する手順を詳細解説。この記事1つで全ての設定が完了する。
-
-
CakePHP 2.3 Search Pluginで検索処理 その2表示件数を動的に変える方法
CakePHPの検索プラグイン Search Pluginの検索処理の中で動的に表示件数を変える方法です。
-
-
CakePHP4系、CakePHP5系のexists()でカラムを指定して値の有無をチェックする方法解説
CakePHP4、5で指定したカラムに特定の値に該当のレコードの有無をチェックするにはexists()を使う。単純にカラムを指定する方法から複数条件をand、orで探すこともできる。