cakePHPでファイルアップロード機能を自前で実装する
「自前で実装する」といってもcakeForgeのスクリプトの中で、いい感じなのを見つけたのでそれを流用するだけなのだが・・・。
以前アップロードを簡単に実現するためのコンポーネントのことを記事に書いたけど、あれはあれで複雑で自分好みにするのは少し面倒だった。であれば「コンポーネントで実現するよりもべた書きしたほうがいいかもしれない」と思い、どういうふうに記述すればいいのか探してみた。そしたらいいお手本があった。
cakeForgeのフォトアルバムを作成するためのスクリプトだ。この中のphotos_controller.php内の記述が参考になる(addの記述の部分)。
ファイルのアップロードについては、まずこんな具合に取り扱っている(その他のフォーム要素の取り扱いと同じ)。
$this->params[‘data’][‘Photo’]
で、ファイル($_FILES)の各変数を処理しないといけないわけだが、それはこんな具合にして対応できるようだ。
$this->params[‘data’][‘Photo’][‘file’]
最終的にコントローラ内では以下の一行が保存処理になっている。
$this->Photo->savePhoto($this->params[‘data’][‘Photo’][‘file’], $thumbSize, $thumbType)
つまりコントローラから、モデル(この場合はPhoto)に対して「保存処理を実行しなさい」という命令を下し、後はモデルにおまかせしてしまっているのだ。本来データの取り扱いはモデルのお仕事なのだから、これはこれで記述の仕方がスマートなように感じる。次にモデル(photo.php)のほうを見てみる。
function savePhoto($fileData,$thumbSize,$thumbType) {
vendor(‘ccImageResize.class’);
if (move_uploaded_file($fileData[‘tmp_name’], WWW_ROOT . “img/photos/” . $fileData[‘name’])) {
$resizer = new ccImageResize;
if ($resizer->resizeImage(WWW_ROOT . “img/photos/” . $fileData[‘name’], WWW_ROOT . “img/thumbnails/” . $fileData[‘name’],$thumbSize,$thumbType)) {
return true;
} else {
// TODO: Clean up and set error message
return false;
}
} else {
// TODO: Set error message if move_uploaded_file fails
return false;
}
}
別途用意してある画像サイズ変更のためのライブラリが使用されてはいるが、直接関係のあるところは一目瞭然「move_uploaded_file」な部分だ。案外「生」なやり方で書いてある。
でもこのやり方、すごくスマートな気がするので、現在作成中のアプリはこれでいくことにする。