備忘録的な @7wk

phpとjavascript系をメインに扱っていく予定。

FuelPHPのUploadクラスを使ってみる

画像の管理をするにあたりファイルアップロードを使うので
FuelPHPのUploadクラスを使ってみる。
ただデータはファイルではなくデータベースに格納します。

マニュアルでいうとこのあたり。
http://fuelphp.jp/docs/1.5/classes/upload/config.html

そしていつものようにエラーチェックは省略しているので、
万が一にここを見て書く人がいましたらちゃんとチェックして下さい。


まずconfigをコピー。

cp core/config/upload.php app/config/


設定ファイルを編集します。
ファイルに保存しないのでアップロードファイルの種類を限定するのみです。
他はデフォルトのまま設定してあります。

<?

return array(
	// 拡張子がpng, jpg, gifのファイルのみ許可
	'ext_whitelist'	 => array('png', 'jpg', 'gif',),
	// ファイルタイプがimageのモノのみ
	'type_whitelist' => array('image',),
	// png,jpg,gifのみ許可
	'mime_whitelist' => array('png', 'jpg', 'gif', 'jpeg', 'pjpeg', 'x-png',),

);


画像データ格納テーブルの作成
元のファイル名と拡張子、縦横を保持します。

CREATE TABLE `pictures` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(64) NOT NULL DEFAULT '',
  `content` blob NOT NULL,
  `ext` varchar(4) NOT NULL DEFAULT '',
  `width` int(11) NOT NULL,
  `height` int(11) NOT NULL,
  `created` datetime NOT NULL,
  `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

モデルも作成。こちらORMでcreatedは作成日時、
modifiedは更新日時が入るよう設定済みの
\Model\Base_Ormを継承してます。
そしてaddでデータを保存します。

<?php
namespace Model;
class Picture extends \Model\Base_Orm
{
	public static function add($file = array())
	{
		$size = getimagesize($file['file']);
		$data = array(
			'name'    => $file['name'],
			'content' => file_get_contents($file['file']),
			'ext'     => $file['extension'],
			'width'   => $size[0],
			'height'  => $size[1],
		);
		return static::forge($data)->save();
	}
}


Controllerを書きます
自分の環境はがちょっと独自なので誤ってたらすみません。
parserはtwigです。

<?php
namespace Controller;

class Picture extends \Controller
{
	// リスト表示&アップロードフォーム
	public function action_index()
	{
		// リスト表示
		// 処理省略
		$data = array();
		return \Response::forge(\View::forge('picture/index.html', $data));
	}

	// アップロード処理
	public function action_upload()
	{
		// upload
		\Upload::process();
		if (\Upload::is_valid()) {
			$files = \Upload::get_files();
			if ($files) {
				foreach ($files as $file) {
					\Model\Picture::add($file);
				}
			}
		}
		\Response::redirect('picture/index');
	}

	// 画像出力
	public function action_image($id)
	{
		$pic = \Model\Picture::find($id);
		$images = array(
			'png' => 'image/png',
			'jpg' => 'image/jpeg',
			'gif' => 'image/gif',
		);
		$headers = array(
			'Content-type' => $images[$pic->ext],
		);
		return \Response::forge($pic->content, 200, $headers);
	}

}


indexのview

{{ form_open({'action':'picture/upload', 'enctype':"multipart/form-data', 'method':'POST'}) }}
{{ form_file('image') }}
{{ form_submit('', '送信') }}
{{ form_close() }}

一覧表示
> 〜以下略〜

これで画像出力時は

<img src="{{ url('picture/image/' ~ picture.id ~'/image.' ~ picture.ext) }}" width="{{ picture.width }}" height="{{ picture.height }}" />

こんな感じで実装できるかと思います。

以上、今日の備忘録でした。