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固定でしたので、それを可変にし、ついでに元ファイルのファイル名、ファイルサイズといった情報も取得するために、テーブルを拡張したり、そのままではうまく画像が呼び出せなかったために、画像の確認するためのファイルなどを作りましたので、あわせてそちらも紹介いたします。
————–(テーブル)
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)
Form->create('Image', array('action' => 'add', 'type' => 'file')); ?> Form->end(__('画像を追加'));?>
Html->link(__("/images/contents/{$image['Image']['filename']}"), array('action' => "/contents/{$image['Image']['filename']}" ), array ( 'target' => '_blank' ) ); ?>
————–
/View/Images/contents.ctp は、ないとエラーになりますので作成する必要がありますが、中身は空のファイルになります。
————–(/View/Images/contents.ctp)
————–
/Controller/ImagesController.php は、以下のようになります。
それぞれの処理の解説は、参考にしたバシャログさんのサイトを見ていただく方が分かりいいかと思います。
————–(/Controller/ImagesController.php)
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
[amazonjs asin=”4774153249″ locale=”JP” title=”CakePHP2 実践入門 (WEB+DB PRESS plus)”]
ファイルアップロードの表示側の処理
また、http://localhost/cake/images/contents/xxxxxxxx.jpg のような形式では文字化けしたような文字が表示され、なぜかうまく表示されずさんざん悩んだのですが、それを改善させる方法を見つけることはできませんでした。
PDFや、csvファイルは問題なく表示されますが、jpeg、gifなどの画像ファイルが正しく表示されないという不具合でしたので、おそらく「header(‘Content-type:…….」の出力部分がうまく処理されていないのだろうと思うのですが...
ただ、実際の使用方法に近い記述の方法で確認したところ、正しく表示されましたので、それで良しとしたところもあります。
————–(/webroot/test.php)
————–
上記のファイルを作成し、webrootにおいてアクセスすると画像ファイルも無事に表示されましたので、画像も正しくアップロードされていることが確認できました。
ファイル名を乱数にしてセキュリティを向上させる方法
ファイル名を乱数や、指定の値に変更し、セキュリティを向上させる方法も書いていますので、こちらも参考にしてください。
CakePHP 2.3でファイルをアップロード・その2 ファイル名を乱数で設定
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
-
CakePHP3にOGPをfetch、asignを利用してテンプレートごとに指定する方法を解説
CakePHP3でOGPを設定する方法を解説。fetch、assignを使用しレイアウトファイルに編集した変数にテンプレートファイルから値を指定する。これを利用してOGPを編集する。
-
-
CakePHP3でパンくずの指定は HTMLヘルパーを使って指定する方法を解説
CakePHP3でパンくずの指定方法の解説。2つのヘルパーがあるが簡単なHTMLヘルパーを使った方法を、実際の状況に合わせて3つのパターン(エレメント化、ブロック化)にして解説。
-
-
CakePHP3のUpload Plugin 3.0をバリデーションなど実運用向けのカスタマイズ方法解説・その2
CakePHP3でファイル、画像をアップロードするプラグイン、upload plugin 3を導入する手順を解説した記事。3部作のその2でバリデーションなどの実用的なカスタマイズ方法を解説。
-
-
CakePHP4系でJSONレスポンスの処理ではwithStringBodyを使う。3との違い解説
responseの値を指定する方法は3系では「body」だが、4系では「withStringBody」になりる。加えてJSON形式なら「withType」で指定するなど4系では結構異なる処理がある。
-
-
CakePHP2の検索Plugin CakeDC/Searchで重複を省くgroup by(distinct)の実装方法
CakePHP2の検索プラグイン「CakeDC/Search」で、重複レコードを省くgroup by、distinctを使う方法についての解説。設定する場所はpaginatorの条件とするので、find()関数と同じ。
-
-
CakePHP3にデザインテンプレートBootstrapを導入する方法・friendsofcake/bootstrap-ui使用
CakePHP3にプラグイン「friendsofcake/bootstrap-ui」、デザインテンプレート「Bootstrap」を設置する手順を解説。Bootstrapの簡単な使い方やデフォルトのデザインとの混在方法なども解説。
-
-
Windows上のXAMPP環境のCakePHPのコマンド実行時に環境変数を指定する方法
CakePHP4のコマンド(シェル)に対して、環境変数を指定して実行する方法を解説。LinuxとWindows上のXAMPPとでは記述方法が異なるため、Windowsのsetコマンドについても詳細解説。
-
-
国際化と地域化の翻訳機能「__()」を使って定数に変数を埋め込む方法
CakePHP4で定数に変数を埋め込み、翻訳機能「__()」で変数に値を入れる方法を紹介。定型の文章の一部だけを置換したい場合に利用すると便利。
-
-
CakePHP3のタイムゾーンを協定世界時UTCから日本標準時間JSTにずれを変更する方法
CakePHP3の標準設定のタイムゾーンは「UTC(協定世界時)」に設定されている。これを日本標準時に変更する方法(app.php、bootstrap.phpの変更方法)の解説。
-
-
CakePHP3で静的ページの作成は webrootか pagesを使う。トップページを参考に解説
CakePHP3で静的なページを設置する場合の方法(webrootとpagesとを活用する方法)を解説。pagesの解説はデフォルトのトップページがどう表示されているかを参考に解説。ルーティングの機能も。