FuelPHPのUploadクラスを詳しくまとめてみる。
今回はFulephpのUploadクラスについてまとめています。多少のPHPの知識を知っているという認識で詳しく書こうと思います。
概要
FuelPHPのUploadクラスは、ファイルのアップロードを簡易的にしてくれるクラスです。しかしながら多少クセがあり、感覚がつかみにくいところがあります。(入力部分がブラックボックスすぎて)
基本ソース
■view部(わざとPHPは使用しない形で書いてます)
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="upload_file">
<input type="submit" name="submit" value="送信">
</form>
■sample.php
class Controller_Sample extends Controller
{
public function action_index()
{
// 2016/03/16 追記
// ver1.6.1以降、同じアクションでgetとpostを処理する場合は
// ファイルがアップされる際のmethod判定が必要みたいです。
if(Input::method() === 'POST') {
// 初期設定
$config = array(
'path' => DOCROOT.DS.'files',
'randomize' => true,
'ext_whitelist' => array('img', 'jpg', 'jpeg', 'gif', 'png'),
);
// アップロード基本プロセス実行
Upload::process($config);
// 検証
if (Upload::is_valid())
{
// 設定を元に保存
Upload::save();
// 情報をデータベースに保存する場合
Model_Uploads::add(Upload::get_files());
}
// エラー有り
foreach (Upload::get_errors() as $file)
{
// $file['errors']の中にエラーが入っているのでそれを処理
}
}
}
}
あれ?$_FILESはどこに行ったの?
自分はここで詰みそうになりました。$_FILES無いのにどうやって処理するんだよ!って。
結論をいうと、Upload::prosessメソッドに内包されていました。
prosessメソッドを使用すると自動的にクラス内の$files変数に入るようです。
例として、
自分で「サイト支援サイト.jpg」をアップし、Upload::process($config)を行ったあと、Upload::get_files()のvar_dumpを取ったもの。
array(1) {
[0]=>
array(10) {
["name"]=>
string(28) "サイト支援サイト.jpg"
["type"]=>
string(10) "image/jpeg"
["error"]=>
bool(false)
["size"]=>
int(472577)
["field"]=>
string(11) "upload_file"
["file"]=>
string(14) "/tmp/phpsh3Frt"
["errors"]=>
array(0) {
}
["extension"]=>
string(3) "jpg"
["filename"]=>
string(24) "サイト支援サイト"
["mimetype"]=>
string(10) "image/jpeg"
}
}
ちなみに、ファイルをアップしなかった場合は、array(0){}になってました。
で、じゃあfilesには何が入ってんの?
と、いう話になりますね。まあvar_dump取ったからほとんど書いてますけども。
表形式でまとめました。
Key | 型 | 説明 |
---|---|---|
field | string | フォームのinputタグに入っていたname名。nameに[]をつけていた場合は field:0となる。 |
name | string | アップロードしたファイル名 |
type | string | アップロードされたブラウザ上でのMIMEタイプ。 |
mimetype | string | よく分からなかったのですが、別途で判別出来る場合はそれで判別したMIMEタイプが入るようです。判別出来なかった場合はtypeと同じ値 になります。 |
file | string | アップロードされたファイルの場所 |
filename | string | アップロードされたファイル名 |
extension | string | ファイルの拡張子(自動的に小文字にはなりません) |
size | integer | ファイルサイズ。単位はバイト。 |
error | boolean | エラーがあるかどうか |
errors | array | エラーを連想配列に入れてある。array(‘error’ => エラーコード, ‘message’ => メッセージ)という形 |
また、Upload::save()を呼び出した後は、以下の2つのフィールドが追加されます。
Key | 型 | 説明 |
---|---|---|
saved_to | string | 保存される場所のパス |
saved_as | string | 保存の際のファイル名 |
configに関して
configに関しては、日本語ドキュメントが充実しているの省きます。
FuelPHP 1.5 日本語ドキュメント Upload 設定
エラー文に関して
エラー文はcore/lang/en/upload.phpに書いてあります。
必要であれば、日本語化をしておきましょう。まだ自分は日本語にしてません・・・。(誰か日本語化してgistとかに上げてほしいな・・・チラッチラッ)
<?php
return array(
'error_'.\Upload::UPLOAD_ERR_OK => 'The file uploaded with success',
'error_'.\Upload::UPLOAD_ERR_INI_SIZE => 'The uploaded file exceeds the upload_max_filesize directive in php.ini',
'error_'.\Upload::UPLOAD_ERR_FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
'error_'.\Upload::UPLOAD_ERR_PARTIAL => 'The uploaded file was only partially uploaded',
'error_'.\Upload::UPLOAD_ERR_NO_FILE => 'No file was uploaded',
'error_'.\Upload::UPLOAD_ERR_NO_TMP_DIR => 'Configured temporary upload folder is missing',
'error_'.\Upload::UPLOAD_ERR_CANT_WRITE => 'Failed to write uploaded file to disk',
'error_'.\Upload::UPLOAD_ERR_EXTENSION => 'Upload blocked by an installed PHP extension',
'error_'.\Upload::UPLOAD_ERR_MAX_SIZE => 'The uploaded file exceeds the defined maximum size',
'error_'.\Upload::UPLOAD_ERR_EXT_BLACKLISTED => 'Upload of files with this extension is not allowed',
'error_'.\Upload::UPLOAD_ERR_EXT_NOT_WHITELISTED => 'Upload of files with this extension is not allowed',
'error_'.\Upload::UPLOAD_ERR_TYPE_BLACKLISTED => 'Upload of files of this file type is not allowed',
'error_'.\Upload::UPLOAD_ERR_TYPE_NOT_WHITELISTED => 'Upload of files of this file type is not allowed',
'error_'.\Upload::UPLOAD_ERR_MIME_BLACKLISTED => 'Upload of files of this mime type is not allowed',
'error_'.\Upload::UPLOAD_ERR_MIME_NOT_WHITELISTED => 'Upload of files of this mime type is not allowed',
'error_'.\Upload::UPLOAD_ERR_MAX_FILENAME_LENGTH => 'The uploaded file name exceeds the defined maximum length',
'error_'.\Upload::UPLOAD_ERR_MOVE_FAILED => 'Unable to move the uploaded file to it\'s final destination',
'error_'.\Upload::UPLOAD_ERR_DUPLICATE_FILE => 'A file with the name of the uploaded file already exists',
'error_'.\Upload::UPLOAD_ERR_MKDIR_FAILED => 'Unable to create the file\'s destination directory',
);
Upload::registerに関して
Upload::registerメソッドは特定のメソッドの際にコールバックとして処理を追加することができます。これにより、バリデーションを追加したり、ファイルの保存先を拡張子別に変えたりすることができます。
Upload::register($event, $callback) $eventにはvalidate(検証時),before(save()が行われる前),after(save()が行われた後)を指定できる。 コールバックには$fileが入る。
また、Upload::registerメソッドは基本的にprocessメソッドが呼ばれる前に行っておきましょう。(正確に言えば、validateを指定する場合はproccessより前で、beforeやafterを指定する場合はsaveより前に指定をしてください。)
Example – 拡張子によって保存先を切り替える
Upload::register('before', function (&$file) {
if ($file['error'] == Upload::UPLOAD_ERR_OK)
{
switch($file['extension'])
{
case "jpg":
case "png":
case "gif":
// 画像データであればimages/に入れる
$file['saved_to'] .= 'images/';
break;
case "css":
// cssファイルならcss/に
$file['saved_to'] .= 'css/';
break;
case "js":
// javascriptならjs/に
$file['saved_to'] .= 'js/';
break;
default:
// 他のファイルは通常の設定に従う
}
}
});
このようにすることで、動的に保存先を切り替えることが可能です。
また、こちらで定義された、$fileですが、上の方で説明した$filesの中身がそのまま入っています。
まとめ
・最初は迷ったけど、Uploadクラスは結構便利。
・コールバックが使える。
という感じですね。
慣れてしまえば、いろいろと利用出来そうです。ただ、Uploadされたファイルに限定されるので、URLで指定したファイルを動的に出来たら良かったかな・・・って感じです。
コメント