【PHP】FuelPHPでファイルアップロード

FuelPHPでファイルをアップロードする方法をまとめます。

以下の公式ページを参考に実装しました。

http://fuelphp.jp/docs/1.8/classes/upload/usage.html

要件

  1. inputタグで指定されたファイルをアップロードする
  2. ファイル名はハッシュ値に置き換える
  3. ファイルの最大サイズは1MB
  4. ファイル拡張子はjpeg, jpg, gif, pngのみ許可
  5. エラーは発生した時点で例外とする

実装

フロント側

Submit form内に以下を追加します。

<input type="file" name="image" accept="image/*" />

サーバー側実装

モジュール定義

FuelPHPのコアライブラリを使用するので以下を追加します。

use \Fuel\Core\Upload;

アクションの実装

// アップロードファイルの設定
Upload::process(array(
    'path'          => '/var/tmp',
    'overwrite'     => true,
    'randomize'     => true,
    'max_size'      => 1000000,
    'ext_whitelist' => array(
        'jpeg',
        'jpg',
        'gif',
        'png'
    )
));

// アップロードファイルの検証と保存
if (Upload::is_valid()) {
    // 画像アップロード成功の場合、設定を元に保存
    for($i = 0; $i < count(Upload::get_files()); $i++) {
        Upload::save($i);
    }
}

// ファイルアップロードエラー
foreach (Upload::get_errors() as $file) {
    foreach($file['errors'] as $error) {
        // ファイル未指定のエラーは無視
        if($error['error'] != Upload::UPLOAD_ERR_NO_FILE) {
            throw new \FuelException($error['message'], $error['error']);
        }
    }
}

※ファイル未指定の場合もエラーになってしまうのでスキップするようにしました。

必須項目の場合はエラーで良いでしょうが、任意項目の場合はこのように Upload::UPLOAD_ERR_NO_FILE であればスキップする処理を入れると良いです。

エラー例

上記の実装で確認できるいくつかのエラーを記載しておきます。

容量が指定サイズより大きい

array(2) {
  ["error"]=>
  int(1)
  ["message"]=>
  string(70) "The uploaded file exceeds the upload_max_filesize directive
in php.ini" }

拡張子が指定されたもの以外

array(2) {
  ["error"]=>
  int(103)
  ["message"]=>
  string(50) "Upload of files with this extension is not allowed"
}

備考

error要素にはUploadクラスに定義されている定数が入って来ます。

例)

  • Upload::UPLOAD_ERR_INI_SIZE = 1
  • Upload::UPLOAD_ERR_EXT_NOT_WHITELISTED = 103

詳細は冒頭の リンク

成功時の例

array(1) {
  [0]=>
  array(12) {
    ["field"]=>
    string(11) "image"
    ["saved_as"]=>
    string(36) "7df248cea0c368722030b3cdeb2f9f16.png"
    ["name"]=>
    string(15) "test_image.png"
    ["type"]=>
    string(9) "image/png"
    ["file"]=>
    string(14) "/tmp/phptzucRW"
    ["error"]=>
    bool(false)
    ["size"]=>
    int(302858)
    ["extension"]=>
    string(3) "png"
    ["basename"]=>
    string(11) "image"
    ["mimetype"]=>
    string(9) "test_image/png"
    ["saved_to"]=>
    string(9) "/var/tmp/"
    ["errors"]=>
    array(0) {
    }
  }
}

この例だと /var/tmp/7df248cea0c368722030b3cdeb2f9f16.png にアップロードされているので、これをプロジェクトのpublicディレクトリに持っていくなり、S3にアップロードするなりすればOKです。

コメント

このブログの人気の投稿

docker-compose up で proxyconnect tcp: dial tcp: lookup proxy.example.com: no such host

docker-compose で起動したweb、MySQLに接続できない事象

【PHP】PHP_CodeSnifferを使う(コーディングルールのカスタマイズ)