開発メモ,主に補足by子連れ親父プログラマー

2011-10-03

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 配列に画像のパスを追加してるだけです。

このブログを検索

Powered by Blogger.

ラベル

php (17) jQuery (13) OSX (10) MySQL (8) Javascript (7) Postgres (7) port (7) apache (6) Java (3) Smarty (2) html (2) pear (2) FCKEditor (1) XAMPP (1) css (1) git (1) perl (1) ruby (1)

Facebookバナー