画像のアップロード処理をつくる【I】(CakePHP修行 #26)

SPONSORED LINK

Pocket

さてCakePHP修行。Rapid開発のためのフレームワークなのにもたもたしていてはいけません。すみません、すみません。

今日は画像アップロード処理。考えている仕様は以下のとおり。

  • 画像はJPEG/GIF/PNGなどがアップ可能。
  • 1ユーザーにつき1枚の画像がアップ可能。
  • アップした画像は適当に縮小される。
  • アップした画像は/webroot/pics以下にUserIDをファイル名として格納される(0001.jpgとか)
  • 画像の削除ももちろん可能。

さてではいってみましょう。なお、長くなりそうなので今回はパートIということで。

■ MAX_FILE_SIZEにはヘルパーつかえんのか?

さてまずはedit.htmlを変更したいのですが・・・MAX_FILE_SIZEの指定ではまりました。これってhtml helperでできないのかしらん?

<?= $html->hidden('MAX_FILE_SIZE', array('value'=>'30000')); ?>

上のようにやってみてもエラーになってしまいます。しょうがないのでそのままhidden属性のinputタグを書いてしまいました。これはこれでいいのかな?

あとはFormのenctypeを入れたり、実際アップするinputタグをいれたりで、結局できたedit.thtmlは次のとおり(Form部分だけね)。

<form action="<?= $html->url('/users/edit'); ?>" method="post" enctype="multipart/form-data">
<?= $html->hidden('User/id'); ?>
<input type="hidden" name="MAX_FILE_SIZE" value="30000" />
<table border="0" cellspacing="2" cellpadding="2" width="100%">
<tr valign="top">
<td align="right">Name</td>
<td><?= $html->input ('User/name', array('size'=>'40')); ?></td>
</tr>
<tr valign="top">
<td align="right">Email</td>
<td><?= $html->input ('User/email', array('size'=>'40')); ?><?= $html->tagErrorMsg('User/email', '<span class="err">Email is required.</span>'); ?></td>
</tr>
<tr valign="top">
<td align="right">Password</td>
<td><?= $html->password ('User/pwd', array('size'=>'20', 'value'=>'')); ?></td>
</tr>
<tr valign="top">
<td align="right">Profile</td>
<td><?= $html->textarea('User/profile', array('cols'=>'38', 'rows'=>'10')); ?></td>
</tr>
<tr valign="top">
<td align="right">Picture</td>
<td><?= $html->file('User/pic'); ?></td>
</tr>
<tr valign="top">
<td>&nbsp;</td>
<td><?= $html->submit('Update') ?></td>
</tr>
</table>
</form>

■ ファイルをどこにどうアップするか?

アップする画像ファイルの種類は限定したくないので、拡張子も含めてUsersテーブルに格納したいところ。まずはテーブル設計に変更を加えます。

CREATE TABLE users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50),
    email VARCHAR(255) BINARY NOT NULL UNIQUE,
    pwd VARCHAR(255),
    pic VARCHAR(255),
    profile TEXT,
    created DATETIME DEFAULT NULL,
    modified DATETIME DEFAULT NULL
);

↑ picフィールドを足しました。

次にファイルアップ先の/webroot/picsを作り、Permissionを与えます(777にしたけどいいのかな?)。

ここまでやったあとにusers_controller.phpを次のように変更。

function edit ()
{
  $this->pageTitle = 'Edit My Profile';
  $this->checkSession();
  $this->set('me', $this->User->findById($this->Session->read('my_id')));
  $this->User->id = $this->Session->read('my_id');
  if (empty($this->data))
  {
    $this->data = $this->User->read();
  }
  else
  {
    $this->data['User']['pwd'] = isset($this->data['User']['pwd']) ? sha1(PWD_KEY.$this->data['User']['pwd']) : $this->User->read('pwd');
    if (isset($this->data['User']['pic']))
    {
      $ext = strtolower(preg_replace("!.*\.!", null, $this->data['User']['pic']['name']));
      $filename = sprintf("%05d.%s",$this->User->id, $ext);
      move_uploaded_file($this->data['User']['pic']['tmp_name'], APP."webroot/pics".DS.$filename);
      $this->data['User']['pic'] = $filename;
    }
    if ($this->User->save($this->data['User']))
    {
      $this->Session->write('sys_msg', 'Your profile has been updated.');
      $this->redirect('/users/home/');
    }
  }
}

細かいですが、APPのように/app/webroot/を指す定数はないのだろうか・・・。ちょっと気になる。

さて実際にテストしてみるときちんとファイルがアップされているようです。

upload.gif

↑ 画像ファイルがアップされました!

しかしまだまだ残作業がありますね。

  • エラー処理(大きすぎるファイルははじきたい)
  • 適当に縮小したい。
  • アップしてあるファイルの削除機能をつけたい。
  • セキュリティ?

まずはこんなところで。パートIIへ続きます。

※ CakePHP修業は百式管理人がSNSっぽいものをCakePHPで作ろうとして挫折するまでの日記です。前回までのあらすじはこちらへ。

ツイッターもやっています!

SPONSORED LINK

  1. No comments yet.

  1. No trackbacks yet.