画像のアップロード

Cakephp(Cakephp1.2RC2現在)には、便利な画像アップロード機能くらいあると思っていたが、そうでもないようだ。

管理画面のカテゴリ管理で、カテゴリ情報に画像をつけたい。特にデータベースに画像データを格納する必要はない。ただ画像ファイルをWebからアップロードしてサーバ上に格納し、カテゴリデータにはそのパスを記録するようにする。

今回参考にさせていただいたのは下記のページ。

CakePHP jQuery を使用した Ajax ファイルアップロード | Sun Limited Mt.

他にもやり方はあるのだろうと思うが、このやり方を選んだ理由の一つはAjaxを使ってみたかったから。。。

ほとんど参考ページにあるやり方そのままで、簡単にできてしまった。

jquery.jsとjquery.form.jsは、あいにくどこからとってきたか忘れてしまったが、結構探し回ったような気がする。
これらを/app/webroot/jsに格納して、実際に画像をアップロードさせるビューで指定。

/app/views/categories/admin_add.ctp

PHP:
  1. echo $javascript->link('jquery-1.2.6');
  2. echo $javascript->link('jquery.form');

さらに、ファイルアップロード用の入力項目を設置
/app/views/categories/admin_add.ctp

PHP:
  1. echo $form->input('upload_file', array('type' => 'file', 'label' => '画像ファイル'));
  2. echo $form->button('アップロード',array('onClick' => "$('#CategoryAddForm').ajaxSubmit({target: '#uploadFile',url: '/admin/categories/upload/'}); return false;"));
  3. echo '<div id="uploadFile">';
  4. echo '</div>';

上記のソースで下記のような感じになる。

ファイルアップロードフォーム例

ファイルアップロードフォーム例

アップロードボタンのonClickにある、「#CategoryAddForm」の部分はFormタグのid。
特にビューでFormタグのidを指定していないけれど、データを追加(ADD)するフォームであれば、Formの冒頭として下記のような記述がしてあれば、自然とFormタグにid="CategoryAddForm"が指定される。
/app/views/categories/admin_add.ctp

PHP:
  1. echo $form->create('Category', array('type' => 'file'));

また、「target: '#uploadFile'」の部分は、AJAXでの作業結果が返ってくる場所のことだろう。今回は、直下に
id="uploadFile"を指定したdivタグを用意した。
最後の「url: '/admin/categories/upload/'」の部分はAJAXで処理する作業のコントローラを指定しているようだ。

で、そのAJAXで処理する作業のコントローラのほうは、下記のような感じ。
/app/controllers/categories_controller.php

PHP:
  1. function admin_upload() {
  2.     if (!$this->data['Category']['upload_file']) {
  3.       $this->set('error', 'アップロードするファイルを選択してください');
  4.       $this->render('admin_upload','ajax');
  5.     } else {
  6.       $filename = '';
  7.       if ($this->data['Category']['upload_file']['type'] == 'image/jpeg') {
  8.         $filename = intval(rand()) . '.jpg';
  9.       } elseif ($this->data['Category']['upload_file']['type'] == 'image/pjpeg') {
  10.         $filename = intval(rand()) . '.jpg';
  11.       } elseif ($this->data['Category']['upload_file']['type'] == 'image/gif') {
  12.         $filename = intval(rand()) . '.gif';
  13.       } elseif ($this->data['Category']['upload_file']['type'] == 'image/png') {
  14.         $filename = intval(rand()) . '.png';
  15.       } elseif ($this->data['Category']['upload_file']['type'] == 'image/x-png') {
  16.         $filename = intval(rand()) . '.png';
  17.       }
  18.       if ($filename) {
  19.         if (is_writeable(IMAGES)) {
  20.           rename($this->data['Category']['upload_file']['tmp_name'], IMAGES . $filename);
  21.           $this->set('filename', $filename);
  22.           $this->render('admin_upload','ajax');
  23.         } else {
  24.           $this->set('error', '画像フォルダ(' . IMAGES . ')に書き込みできません。');
  25.           $this->render('admin_upload','ajax');
  26.         }
  27.       } else {
  28.         $this->set('error', '画像ファイルではありません。');
  29.         $this->render('admin_upload','ajax');
  30.       }
  31.     }
  32.   }

今回は、JPEGとGIFとPNGをアップロードできるようにしてみた。

上記のコントローラの作業の結果は、先ほどのid="uploadFile"を指定したdivタグに表示されるのだが、その表示内容もあらかじめビューで記述しておく。
/app/views/categories/admin_upload.ctp

PHP:
  1. <?php header("Content-Type: text/html;charset=UTF-8"); ?>
  2. <?php if (!empty($error)): ?>
  3. <p><?php echo $error;?></p>
  4. <?php else: ?>
  5. <p>画像をアップロードしました。</p>
  6. <?php echo $html->image($filename); ?>
  7. <?php echo $form->input('Category.image', array('type' => 'text', 'label' => '画像パス', 'value' => $filename)); ?>
  8. <?php endif; ?>

headerでcharsetを送っておかないと、文字化けするのでちょっと注意が必要だ。

画像をアップした後のフォームはこんな感じ。

AJAXでファイルアップロードした結果画面

AJAXでファイルアップロードした結果画面

今回はとりあえずAJAXを使ってみました、という程度だが、本来であればもっといろいろとできることがあるんだろう。徐々によくしていきたい。

Tags: ,