Dream of Electric Sheep

WEBやプログラムの忘備録

CakePHP 2.5.8. でファイルのアップロード

タイトルの通り、ファイルのアップロードを試してみました。
コードは以下の通りです。

・POSTするHTML側

 <form action="[コントローラーのURL]" enctype="multipart/form-data" method="post">
    ・
    ・
     <input name="foo_file" type="file" value="" />
     <input type="submit" value="送信" />
</form>

・受ける側コントローラーのアクションメソッド

function index() {
        //パラメータよりイメージ情報を取得
        $image = $this->params['form']['foo_file'];
        
        //イメージ保存先パス
        $img_save_path = IMAGES.DS.'save_files' ;
        
        //イメージの保存処理
        move_uploaded_file($image['tmp_name'], $img_save_path.DS.$image['name']);
}

結果、できてしまえばたった3行で済んだのですが、これだけ調べるのに昨日の午後まるまる使ってしまいました。

まず、送る側の <form> タグは属性 enctype="multipart/form-data" を指定します。これはCakePHPに限らずファイルのアップロードをする際には必ずする記述ですね。

で、このフォームから送った <input type="file"> の情報は、コントローラーのアクションメソッド内で、$this->data[パラメーター名] では取り出せません。print_r() を使ったりして調べたところ、<input type="file">に関する情報は $this->params['form'][パラメーター名] で取り出せることがわかりました。

さらに、この中には連想配列複数の情報が含まれており、

[name] => ファイル名
[type] => ファイルの種類
[tmp_name] => アップロードファイルを一時保存したパス
[error] => エラーの数
[size] => ファイルのサイズ

が情報として取得されます。

アップロードされたファイルは [tmp_name] のパスに一時ファイルとして保存され、アクションメソッド終了と同時に一時ファイルは削除される、という動きをしているようです。
なので、アクションメソッドの中で一時ファイルを任意の場所にコピーしてやればファイルのアップロードはできます。
上記アクションメソッド中のコードでは3行目がそのコピー処理を行っていて、2行目はコピー先のパスを生成する処理の記述です。こちらは保存したいパスやファイル名により変わってくる部分です。

ちなみに保存パス生成時に使っている定数で、IMAGES は CakePHP のイメージフォルダのパス([CakePHPのルートパス]/app/webroot/img)、DS はパスセパレータ(OSで使用しているものを自動でつけてくれる Windowsなら\、linuxなら/ など)を表します。