CakePHP1.3で作る会員管理システム(17) 画像アップロード
画像アップロード
今回画像はデータベースにはそのファイル名を登録します。
つまり、 members テーブルの img1 、 img2 はファイル名です。
ということで別途、画像の実体という意味合いで solid1 、 solid2 という名前を用意します。
( img1 、 img2 を使い回すと面倒なことになるので)
登録する画像はとりあえず、/app/wwwroot/files の中に保存することにします。
まず add.ctp を書き換えます。
echo $this->Form->input('img1'); echo $this->Form->input('img2');
こうなっているところを、
echo $this->Form->input('solid1', array('type'=>'file', 'label' => '画像1')); echo $this->Form->input('solid2', array('type'=>'file', 'label' => '画像2'));こうします。
おっと、
formを enctype=”multipart/form-data” にしないといけませんので。
<?php echo $this->Form->create('Member', array('type'=>'file')); ?>に変えます。
これで、出力は
<form accept-charset="utf-8" method="post" enctype="multipart/form-data" id="MemberAddForm" action="/~myname/cake/members/add">となります。 /app/models/member.php を開いて、モデルの validate を追加します。
'solid1' => array( 'rule1' => array( 'rule' => array('imgType', 'solid1'), 'message'=>'画像1はJPEG形式で登録してください', ), ),
これは ’solid2‘ についても同じように追加しておきます。
いわゆるCakePHP本家Docの4.1.5.2 Adding your own Validation Methodsのやり方なので、自分で ‘imgType’ という名前の function を作ります。
array(‘imgType’, ’solid1′), のうしろの ’solid1′ はその function に渡す引数になります。
以下の function imgType を作って member.php の下の方に入れておきます。
function imgType($data, $name){ if (!$this->data['Member'][$name]['type'] || ($this->data['Member'][$name]['type'] == 'image/pjpeg') || ($this->data['Member'][$name]['type'] == 'image/jpeg')) { return true; } else { return false; } }
単に画像の type が jpeg がどうかをチェックしているだけです。
他にファイルサイズのチェックとか、ファイル名のチェックとか、入れたければ入れます。
で、ちょっとブラウザからテストしてみます。
gif画像なんかを登録した時に、ちゃんと「画像1はJPEG形式で登録してください」のエラーが出たでしょうか。
最後にコントローラ members_controller.php に画像を保存する処理を追加します。
確認画面の時に作った validates の下に、
if ($this->data['Member']['mode'] == 'confirm') { $this->Member->set($this->data); if ($this->Member->validates($this->data)) { if ($this->data['Member']['solid1']['type']){ $this->data['Member']['img1'] = $this->_imgUpload('solid1'); } if ($this->data['Member']['solid2']['type']){ $this->data['Member']['img2'] = $this->_imgUpload('solid2'); } $this->set('member', $this->data); $this->render('confirm'); } else { $this->Session->setFlash(__('エラーがあります', true)); } } elseif ($this->data['Member']['mode'] == 'back') {とします。
ここの _imgUpload は画像を保存するための function で、自分で作ります。
solid1 の画像実体を保存し、その時に画像のファイル名を生成して、そのファイル名を img1 として返します。
function _imgUpload($name) { if ($this->data['Member'][$name]['tmp_name']){ $fd = fopen($this->data['Member'][$name]['tmp_name'], "r"); $filesize = $this->data['Member'][$name]['size']; $filedata = fread ($fd, $filesize); fclose ($fd); $img_file = md5($filedata). ".jpg"; $res = fopen(WWW_ROOT . "files/" . $img_file,'w'); fwrite($res,$filedata); fclose($res); return $img_file; } }
こんな感じです。とりあえず、同じコントローラの下の方に入れておきます。 確認画面 confirm.ctp に表示されるよう修正します。
こうなってるのを、
<dt<?php if ($i % 2 == 0) echo $class;?>><?php __('Img1'); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php echo $member['Member']['img1']; ?> </dd>こうします。
<dt<?php if ($i % 2 == 0) echo $class;?>><?php __('画像1'); ?></dt> <dd<?php if ($i++ % 2 == 0) echo $class;?>> <?php if (isset($member['Member']['img1'])){ echo $this->Html->image("/files/".$member['Member']['img1']);} ?> </dd>
hidden 部分には
echo $this->Form->input('solid1.type', array('type'=>'hidden')); echo $this->Form->input('solid1.size', array('type'=>'hidden')); echo $this->Form->input('solid2.type', array('type'=>'hidden')); echo $this->Form->input('solid2.size', array('type'=>'hidden'));を追加します。
確認画面で画像が表示されたでしょうか。
最後、メールの添付ファイルに指定します。
members_controller.php に戻って、addアクションの、saveしてるところの下に以下を追加します。
$this->Member->create(); if ($this->Member->save($this->data)) { $this->set('member', $this->data); $attachments = array(); if ($this->data['Member']['img1']){ $attachments[] = WWW_ROOT . "files/" . $this->data['Member']['img1']; } if ($this->data['Member']['img2']){ $attachments[] = WWW_ROOT . "files/" . $this->data['Member']['img2']; }
$attachments 配列に画像のパスを追加してるだけです。