Zend Framework コードリーディング (2)

ファイルアップロード機能を追加してみます。ファイルはデータベースに格納します(ロードバランシング環境で必須なので)。PostgreSQL を使っていますが、MySQL でもほとんどそのまま動くと思います。PHP は始めたばっかりなので、おかしいところがあるかもしれません。エラーチェックも適当です。

file_data.sql

CREATE TABLE file_data (
    id SERIAL PRIMARY KEY NOT NULL,
    file_size INTEGER DEFAULT '0' NOT NULL,
    file_type TEXT NOT NULL,
    file_data TEXT NOT NULL
);

application/controllers/TestController.php

<?php
class TestController extends Zend_Controller_Action {
    /** データベースのハンドルを返す */
    private function getHandle() {
        $db = new Zend_Db_Adapter_Pdo_Pgsql(
            Array(
                'host'     => '127.0.0.1',
                'username' => 'hogehoge',
                'password' => 'xxxxxxxx',
                'dbname'   => 'something'
            )
        );
        return $db;
    }

    /** /test/view/id/xx */
    public function viewAction() {
        // ビューを無効にする
        $this->_helper->layout->disableLayout();
        $this->_helper->viewRenderer->setNoRender();

        // ファイルを取得
        $file = $this->getHandle()->fetchRow(
            'SELECT * FROM file_data WHERE id = ?;', 
            $this->getRequest()->getParam('id')
        );
        if ( null !== $file ) {
            // バイナリを返す
            $this->getResponse()->setHeader(
                'Content-Type', 
                $file['file_type']
            );
            print base64_decode($file['file_data']);
        } else {
            // 404 を返す
            $this->getResponse()->setRawHeader(
                'HTTP/1.1 404 Not Found'
            );
            print '404 Not Found';
        }
    }

    /** /test/upload */
    public function uploadAction() {
        if ( $this->getRequest()->getParam('btn_upload') ) {
            // 200KB以下
            if ( $_FILES['picture']['size'] <= 200000 ) {
                // JPEG/GIF/PNGのみ
                if ( $_FILES['picture']['type'] == 'image/jpeg' || 
                     $_FILES['picture']['type'] == 'image/gif' || 
                     $_FILES['picture']['type'] == 'image/png' )
                {
                    // ファイル新規登録
                    $this->getHandle()->insert(
                        'file_data',
                        Array(
                            'file_size' => $_FILES['picture']['size'],
                            'file_type' => $_FILES['picture']['type'],
                            'file_data' => base64_encode(
                                file_get_contents(
                                    $_FILES['picture']['tmp_name']
                                )
                            )
                        )
                    );
                }
            }
        }
    }
}

application/views/scripts/test/upload.phtml

<html>
<body>
  <form enctype="multipart/form-data" action="/test/upload" method="post">
    <input type="hidden" name="MAX_FILE_SIZE" value="200000" />
    <table border="0">
      <tr>
        <th>
          <img src="/test/view/id/1">
        </th>
      </tr>
      <tr>
        <th>
          <input type="file" name="picture">
        </th>
      </tr>
      <tr>
        <td>
          ※最大200KB。JPEG/GIF/PNG 形式のみです。
        </td>
      </tr>
      <tr>
        <th><input type="submit" name="btn_upload" value=" アップロード "></th>
      </tr>
    </table>
  </form>
</body>
</html>