IT女子のお気に入りフォルダ

管理人の備忘録と実践を兼ねた(出来るだけ)役に立つ情報を配信するブログです。

[fuelPHP] ファイルアップロード(Uploadクラス)

HTMLフォームからのファイルアップロードには、Uploadクラスを使うと便利です。

設定ファイルを配置

許可する拡張子とか、最大サイズなどは設定ファイルにまとめて指定することができます。

COREPATH/config/upload.phpを
APPPATH/configにコピーします。
自分のサイトで変更が必要な項目のみ指定することでオーバーライドできます。

アクション毎に変えたい項目(例えば、アップロードファイルの保存先など)は、コントローラでUploadクラスを利用するとき、Upload::process()に指定することでAPPPATH/config/upload.phpファイルの設定をオーバーライドすることが可能です。

主な設定項目

auto_process Uploadクラス利用時に自動的process()メソッドを実行するかどうか。
max_size ファイルアップロードの最大サイズをバイトで指定。0を指定すると無制限(php.iniの設定に依存)。
ext_whitelist 許可する拡張子の配列。空または未定義の場合、すべて許可。
type_whitelist 許可するファイルタイプの配列。(type/subtypeのtypeの部分)
mime_whitelist 許可するMIMEタイプの配列。
prefix アップロードファイルを保存するときに付加する接頭辞。
path アップロードファイルの保存パス
create_path trueの場合、指定されたパスを自動的に作成する。
path_chmod 作成したパスに設定するディレクトリパーミッション。
auto_rename 指定したパスに同名のファイルが存在する場合に連番をつけてリネームするかどうか。
overwrite 指定したパスに同名のファイルが存在する場合に上書き保存するかどうか。

詳しくはドキュメントを
Upload 設定 – クラス – FuelPHP ドキュメント

データベースを準備

サイト仕様上、アップロードしたファイル情報をデータベースに保存しておきたかったので以下のようなテーブルを準備。対応のModelクラスも作成。

t_photoテーブル
t_photo_id int(12) auto_increment
t_photo_users_id int(11) アップロードしたユーザ
t_photo_saved_as varchar(100) 保存されたファイル名
t_photo_type varchar(20) タイプ
t_photo_size int(8) ファイルサイズ
t_photo_mimetype varchar(20) mimeタイプ
t_photo_saved_to varchar(200) 保存先パス
t_photo_published char(1) 公開フラグ
t_photo_created_at int(11) 作成日時
t_photo_updated_at int(11) 更新日時

Viewとコントローラ

画像ライブラリ(photo/index)から、新規追加画面(photo/add)に遷移し、画像ファイルをアップロードできる(photo/upload)という仕様です。
ファイルをアップロードしたユーザIDとともにデータベースにファイル情報を保存します。

View(photo/addの一部)

<?php if (isset($html_error)): ?>
	<div class="alert alert-danger"><ul><?php echo $html_error; ?></ul></div>
<?php endif; ?>

<?php echo Form::open(array('name'=>'form_upload','action'=>'photo/upload','enctype'=>'multipart/form-data','method'=>'post')); ?>

	<div class="form-group row">
		<div class="col-md-12">
			<label for="exampleInputFile">アップロードするファイル</label>
			<?php echo Form::file('upload'); ?>
		</div>
	</div>

	<div class="form-group row">
		<div class="col-md-2">
			<?php echo Form::submit('submit', '保存', array('class' => 'btn btn-primary')); ?>
		</div>
	</div>

<?php echo Form::close(); ?>

コントローラ

public function action_upload()
{
	// 設定(ファイル保存場所)
	$config = array(
		'path' => DOCROOT . 'uploads/',
	);

	// ユーザIDを取得
	list(, $userid) = Auth::get_user_id();

	// アップロード実行
	Upload::process($config);

	// 検証
	if (Upload::is_valid())
	{

		// アップロードファイルを保存
		Upload::save();

		// データベース保存
		foreach (Upload::get_files() as $file)
		{
			// 成功したファイルの処理
			// データをセット
			$photo = Model_Photo::forge(array(
				't_photo_users_id' => $userid, // 現在ログインしているユーザーのIDをセット
				't_photo_saved_as' => $file['saved_as'],
				't_photo_type' => $file['type'],
				't_photo_size' => $file['size'],
				't_photo_mimetype' => $file['mimetype'],
				't_photo_saved_to' => $file['saved_to'],
				't_photo_published' => '1',
				't_photo_updated_at' => 0,
			));

			if ($photo->save()) // 保存
			{
				// 登録成功
				Session::set_flash('success', e('画像をアップロードしました。'));
			}
			else
			{
				Session::set_flash('error', '画像をアップロードできませんでした。');
			}
		}
	}

	// エラー有り
	foreach (Upload::get_errors() as $file)
	{
		$html_error = '';
		foreach ($file['errors'] as $error) {
			$html_error .= '<p>'. $error['message'] . '</p>';
		}

		$this->template->title = '画像をアップロードできませんでした。';
		$this->template->content = View::forge('photo/add');
		$this->template->content->set_safe('html_error', $html_error);
		return;
	}

	$this->template->title = '画像ライブラリ';
	$this->template->content = View::forge('photo/index');
}

Upload::get_files()に検証に成功したファイルの情報が、
Upload::get_errors()に失敗したファイルの情報が入ってます。

ここまで、Upload::registerを使わずきてます。
バリデーション追加したり、拡張子によって保存先変えることができたりなど、まだまだ奥が深そう。

参考サイト

FuelPHPでのファイルアップロード – slideshare
FuelPHP ◇ ファイルアップロード処理を実装する – かいはつめも(ken)
FuelPHPのUploadクラスを詳しくまとめてみる。 – 新人Webエンジニアの記録。