Movatterモバイル変換


[0]ホーム

URL:


INSPIRE TECH

  • このウェブサイトをはてなブックマークに追加

CakePHPの超便利なファイルアップロードプラグイン、FileBinderプラグインの使い方をまとめてみた。

CakePHPを利用している上で、一番悩むのがファイルのアップロードとその管理です。

MediaPluginという有名なファイルアップロードプラグインがありますが、高機能・多機能との引き替えに、インストール方法やその利用方法が非常にわかりづらく、さらにプラグインをバージョンアップしただけでエラーを吐いて動かなくなったりと、常時メンテナンス、するプロジェクトに導入するには少々の抵抗があります。

そこで、もっとシンプルで使いやすいファイルアップロードプラグインである、FileBinderプラグインを紹介したいと思います。

FileBinderプラグインの特徴

FileBinderプラグインは、ファイルアップロードに関して下記のような機能を持っています。

  • ファイルサイズの制限やファイルタイプの制限など、アップロードしたファイルのバリデーション
  • ファイルの保存方法を任意のディレクトリに保存するか、DBにバイナリとして保存するか選べる
  • 全てのファイルを1つのテーブルで管理できる
  • 任意のテーブルにファイルの情報を仮想のフィールドとして組み込むことができる

ファイルアップロードで必要とされるであろうほとんどの機能が実装されていて、普通に使う分であれば何一つ不自由はしません。

そして、FileBinderプラグインの特徴と言える機能が、上記でも紹介している、任意のテーブルにファイルの情報を仮想フィールドとして組み込むことができる機能です。

この機能は、特定のテーブルの検索結果に仮想のフィールドを作成し、そこにファイルの情報を埋め込むことで、あたかもそのテーブルにファイルのデータが格納されているかのように扱うことができるのです。

仮想フィールドの例

例えば下記のようなプロフィールを管理するテーブルがあったとします。

  • first_name
  • last_name
  • age
  • blood_type
  • address
  • email
  • phone

このテーブルにはプロフィール画像などを格納するフィールドはありません。
しかし、FileBinderプラグインを用いると、このテーブルの構造に全く手を付けずに、検索結果にプロフィール画像の情報を埋め込む事が可能になります。

  • first_name
  • last_name
  • age
  • blood_type
  • address
  • email
  • phone
  • profile_image
    • file_size
    • file_name
    • file_content_type
    • file_object

この機能は非常に便利です。

テーブルに手を加えなくても良いのでデータベース設計が柔軟になりますし、1つのテーブルにいくつでも仮想フィールドを加えることができるため、仕様変更が発生した場合でも簡単に対応できます。

また、Mediaプラグイン同様にファイルの情報を1つのテーブルで管理できるため、情報の管理がしやすくなるというメリットもあります。

基本的な利用の流れ

FileBinderプラグインの基本的な利用方法は、下記のようになっています。

  1. ファイルの情報を組み込みたいモデルにBindableビヘイビアを組み込む
  2. 上記のモデルにファイルアップロードに関する設定を定義
  3. 上記のモデルを利用するコントローラーにRingコンポーネントを組み込む
  4. ファイルアップロードを含んだフォームをコントローラーに送信
  5. コントローラーでbindUpメソッドを実行
  6. モデルのsaveメソッドでフォームデータを保存

ビヘイビアとコンポーネントを利用するので多少複雑に感じますが、利用し始めると全くその複雑さは感じません。

実行環境

解説は下記の環境を前提に行っています。

  • PHP5系
  • CakePHP 1.3系

CakePHPのバージョンは1.2系でも動作しそうではありますが、実際に試していないので動作保証はできません。

1.2系をご利用の場合は、コンソールからの実行コマンドが一部違ったりするため、その点は読み替えてご利用下さい。

プラグインファイルのダウンロード

下記のURLにアクセスして、最新バージョンをダウンロードして、app/plugins/ ディレクトリ以下に展開してください。

fusic/filebinder – GitHub

Attachmentモデルの作成

まずはファイル情報を格納するためのモデルである、Attachmentモデルを作成します。

プラグインのconfig/ディレクトリ以下にschema.phpファイルがありますが、そのまま実行するとバイナリデータ保存用のフィールドの型指定がCakePHPの許可する型に無いため、エラーが発生してしまいます。

そのため、下記のようにfile_objectフィールドの型をlongtextからtextなどに変更します。

class AppSchema extends CakeSchema {    var $name = 'App';    function before($event = array()) {        return true;    }    function after($event = array()) {    }    var $attachments = array(                           'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),                           'model' => array('type' => 'text', 'null' => false, 'default' => NULL),                           'model_id' => array('type' => 'integer', 'null' => false, 'default' => NULL),                           'field_name' => array('type' => 'text', 'null' => false, 'default' => NULL),                           'file_name' => array('type' => 'text', 'null' => false, 'default' => NULL),                           'file_content_type' => array('type' => 'text', 'null' => false, 'default' => NULL),                           'file_size' => array('type' => 'integer', 'null' => false, 'default' => NULL),                           'file_object' => array('type' => 'text', 'null' => true, 'default' => NULL), // この行のタイプを text に変更                           'created' => array('type' => 'timestamp', 'null' => true, 'default' => NULL),                           'modified' => array('type' => 'timestamp', 'null' => true, 'default' => NULL),                           'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1)),                           'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB')                           );  }

そして、コンソールから先ほどのschema.phpを利用してテーブルを作成します。

コンソールからの実行コマンドが間違えていたのを修正しました。(2011.07.26)

cake schema create -app your_app_name -plugin filebinder -name app

データベースにファイルを保存する場合、先ほど変更したfile_objectフィールドのデータ型を、データベースのコンソールや設定画面から変更しておきましょう。

さもないと、text型では最大サイズの都合から、テキストファイルや小さな画像程度しか保存できなくなってしまいます

また、忘れずにモデルクラスも作成しておきます。
app/models/attachment.php

class Attachment extends AppModel{}

Bindableビヘイビアの組み込み

ファイルアップロードのキモとなるBindableビヘイビアを、ファイルの情報を結び付けたいモデルに組み込みます。

class Profile extends AppModel{public $actsAs = array('Filebinder.Bindable' => array('model' => 'Attachment', // ファイル情報を保存するモデル名'filePath' => WWW_ROOT . 'img' . DS, // ファイルを保存するディレクトリ(絶対パス)'dbStorage' => true, // ファイルをバイナリデータとしてデータベースに保存するか'beforeAttach' => null, // フック関数(ファイル保存前)'afterAttach' => null, // フック関数(ファイル保存後)'withObject' => false, // 検索結果にファイルのバイナリデータを付加するか));}

オプションを指定しない場合、上記の値がデフォルト値として利用されます。

bindFields変数の定義

そして、ファイル情報を結び付ける仮想フィールドの設定を、$bindFieldsというメンバ変数として下記のように定義します。

class Profile extends AppModel{public $actsAs = array('Filebinder.Bindable' => array('model' => 'Attachment','filePath' => WWW_ROOT . 'img' . DS,'dbStorage' => true,'beforeAttach' => null,'afterAttach' => null,'withObject' => false,));public $bindFields = array(array('field' => 'profile_image', // ファイル情報を組み込む仮想フィールド名'filePath' => WWW_ROOT . 'profile_image' // ファイルを保存するディレクトリ(絶対パス)。指定されない場合、ビヘイビアの設定が利用されます。),);}

もし、仮想フィールドを複数指定したい場合は下記のように指定します。

public $bindFields = array(array('field' => 'file_upload_filed_name1','filePath' => WWW_ROOT . 'file1'),array('field' => 'file_upload_filed_name2''filePath' => WWW_ROOT . 'file2'),array('field' => 'file_upload_filed_name3'),);

バリデーションの定義

Bindableビヘイビアにはファイルアップロード専用のバリデーションメソッドが揃っています。

checkContentType
ファイルのメタ情報を制限します。
array('profile_image' => array('rule' => array('checkContentType', array('image/jpeg', 'image/gif', 'image/png'))));
checkExtension
ファイルの拡張子を制限します。
array('profile_image' => array('rule' => array('checkExtension', array('jpg', 'gif', 'png'))));
checkFileSize
ファイルサイズを制限します。KBMBGBなどの単位が利用出来ます。
array('profile_image' => array('rule' => array('checkFileSize', '10MB')));
checkMinFileSize
ファイルの最小サイズを制限します。KBMBGBなどの単位が利用出来ます。
array('profile_image' => array('rule' => array('checkMinFileSize', '10MB')));
funcCheckFile
ユーザー関数でファイルのバリデーションを行います。
array('profile_image' => array('rule' => array('funcCheckFile', 'userFunction')));
notEmptyFile
ファイルの未アップロードを制限します。
array('profile_image' => array('rule' => array('notEmptyFile')));

必要に応じて、仮想フィールドを組み込むモデルにバリデーションを定義します。

class Profile extends AppModel{public $actsAs = array('Filebinder.Bindable' => array('model' => 'Attachment','filePath' => WWW_ROOT . 'img' . DS,'dbStorage' => true,'beforeAttach' => null,'afterAttach' => null,'withObject' => false,));public $bindFields = array(array('field' => 'profile_image','filePath' => WWW_ROOT . 'profile_image'),);public $validate = array('profile_image' => array('fileSize' => array('rule' => array('checkFileSize', '1MB'),'message' => 'ファイルサイズは1MB以内でアップロードしてください。'),'fileExt' => array('rule' => array('checkExtension', array('jpg', 'gif', 'png')),'message' => '許可されていない拡張子を利用しています。')));}

Ringコンポーネントの組み込み

フォームからのデータを受け取るコントローラーに、Ringコンポーネントを組み込みます。

class ProfileController extends AppController{public $components = array('Filebinder.Ring');}

特に設定は必要ありません。

フォームを作成

ファイルアップロードを行うフォームを作成します。
このとき、ファイルを選択する入力フォームは、先ほど定義した仮想フィールドの名前と同一にします。

フォームの内容がおかしかったのを修正しました。 (2011.07.26)

<?php echo $this->Form->create(array('type' => 'file')) ?><dl><dt>性</dt><dd><?php echo $this->Form->text('first_name') ?></dd><dt>名</dt><dd><?php echo $this->Form->text('last_name') ?></dd><dt>年齢</dt><dd><?php echo $this->Form->text('age') ?></dd><dt>血液型</dt><dd><?php echo $this->Form->text('bloodtype') ?></dd><dt>住所</dt><dd><?php echo $this->Form->text('address') ?></dd><dt>メールアドレス</dt><dd><?php echo $this->Form->text('email') ?></dd><dt>電話番号</dt><dd><?php echo $this->Form->text('phone') ?></dd><dt>プロフィール画像</dt><dd><?php echo $this->Form->file('profile_image') ?></dd></dl><?php echo $this->Form->end() ?>

仮想フィールドを複数作成した場合、それに対応した入力フォームを用意しましょう。

BindUpメソッドを実行し、データを保存

フォームのデータを受け取るコントローラーのアクションで、RingコンポーネントののbindUpメソッドを実行し、あと通常通りデータを保存します。

bindUpメソッドはファイルアップロードの前処理を行うメソッドで、このbindUpメソッドを実行しないとファイルが保存されません。

class ProfileController extends AppController{public $components = array('Filebinder.Ring');public function add(){if (!empty($this->data)) {$this->Ring->bindUp();if (!$this->Profile->save()) {// 保存完了}}}}

このとき、bindUpメソッドの引数には、ファイルの保存処理を行うモデル名を指定する事ができます。

このモデル名は、先ほどBindableビヘイビアを組み込んだモデルを指定しますが、省略した場合、自動的にコントローラーの$modelClass変数に定義されたモデルが利用されます。

データが登録されているか確認する

保存したモデルのデータを実際に確認してみます。

$profile = $this->Profile->read();debug($profile);
[Profile] => Array(    [id] => 1    [first_name] => 太郎    [last_name] => 山田    [age] => 25    [blood_type] => A    [address] => 東京都千代田区    [email] => taro.yamada@test.com    [phone] => 03-1234-5678    [craeted] => 2011-07-20 00:00:00    [modified] => 2011-07-20 00:00:00    [profile_image] => Array        (            [id] => 1            [model] => Profile            [model_id] => 1            [field_name] => profile_image            [file_name] => sample.jpg            [file_content_type] => image/jpeg            [file_size] => 65536            [created] => 2011-07-20 00:00:00            [modified] => 2011-07-20 00:00:00            [file_path] => /app/webroot/profile_image/Profile/1/profile_image/sample.jpg            [bindedModel] => Attachment        ))

正しくファイルの情報が結びついて読み出されているのがわかりますね。

注意

この検索結果にファイルの情報を結びつける機能は、ビヘイビアのafterFindメソッドで実現しています。

CakePHPでは、ビヘイビアのaftetFindメソッドは、そのビヘイビアが組み込まれたモデルが直接検索された時にしか呼ばれません

要するに、AというモデルにhasManyで結びつけられたBというモデルがあり、そのBモデルにFileBinderビヘイビアが組み込まれているとします。

この時、Aモデルをfindした結果にBモデルの情報が存在していても、Bモデルの情報にはファイルの情報は結びついて来ません。

これは実に不便なのですが、CakePHPの仕様のため、ビヘイビアではどうすることもできません。

ビューでの使い方

取得したファイルの情報を表示するには、付属のLabelヘルパーが便利です。
Labelヘルパーには下記のような機能があります。

  • ファイル情報の配列からaタグ(リンク)を生成
  • ファイル情報の配列からimgタグを生成
  • ファイルがブラウザから参照出来ない場所にある場合でも、ファイルがダウンロード・表示できるようにURLを生成してくれる

Labelヘルパーの使い方

HTMLヘルパーに似ているので、使い方は簡単です。

ファイル情報からaタグを生成する
echo $this->Label->link($profile['profile_image']);
ファイル情報からimgタグを生成する
echo $this->Label->image($profile['profile_image']);

ファイルの削除

仮想フィールドに登録したデータを削除したい場合、下記のようなフィールドを利用します。

$this->Form->checkbox('profile_image_delete');

仮想フィールド名+_deleteという名称のフィールドが送信された場合、そのフィールドの値が真であれば、対応する仮想フィールドに結びついているファイル情報が削除されます。

とても便利なプラグイン

以上、基本的な使い方を解説しましたが、使い慣れると手放せなくなるほど便利なプラグインです。

ファイルのバージョン生成機能やキャッシュ機能などはありませんが、Mediaプラグインのように面倒なインストールや設定作業が必要ではなく、フック関数を利用することで様々な利用方法が考えられます。

是非一度、利用してみてください。

SHARE

TAGS

RELATED POSTS

SHARE

COMMENTS / PINGBACKS

  • ダメだ
    Commented on

    動かない

  • 家富 正幸
    Commented on

    コメントありがとうございます。
    どういった状況で動かないのか、どういったエラーが発生しているのか、詳しい状況がわかればアドバイス出来ると思うのですが・・。

  • KERBEROS
    Commented on

    twitterでもお世話になりましたが、私も動かなかったので情報集約のために投稿します。

    症状としては
    「Bindableビヘイビアの組み込み」の
    ‘filePath’ => WWW_ROOT . ‘img’ . DS,
    でエラーが起きていて。
    その画像パスがきちんと指定出来ていないせいか、おそらく削除の時にwebrootフォルダごと消えたので断念しました。
    cake1.3.11 PHP5.3.6 Win7

  • 家富 正幸
    Commented on

    コメントありがとうございました。
    ご報告に基づいて、こちらの記載したコードが間違えていなかったかどうか調査してみますので、もうしばらくお待ち下さい。

  • CakePHPでアップロードファイルをDBに組み込む際に便利なプラグインFileBinder
    Pingbacked on

    [...] 参考記事http://inspire-tech.jp/2011/07……er_plugin/ asklife|IT&Life > コンピュータ・IT > [...]

  • 使えそうで使えない?CakePHPのFileBinderプラグイン | カラスノウタBLOG
    Pingbacked on

    [...] 用な記事をどうもありがとうございます。 『CakePHPの超便利なファイルアップロードプラグイン、FileBinderプラグインの使い方をまとめてみた。』 ただこのプラグイン、ところどころすご [...]

  • kezu
    Commented on

    家富様、素晴らしい記事をありがとうございます!

    私もKERBEROSさんと同様のエラーで悩んだのですが、解決いたしましたのでご報告いたします。(すでに解決されていたらすみません)

    オブジェクトプロパティの宣言では演算子が使用できないために
    ‘filePath’ => WWW_ROOT . ‘img’ . DS,
    上記でエラーが出るものと思われます。(結合演算子も使えない)

    解決策として、FileBinder.Bindableを利用するモデルにコンストラクタを追加して、その中でプロパティを設定しました。
    function __construct() {
    $this->actsAs = array(
    “Filebinder.Bindable” => array(
    ‘model’ => ‘Attachment’,
    ‘filePath’ => WWW_ROOT.’files’.DS,

    ),
    );
    $this->bindFields = array(

    );
    parent::__construct();
    }

    もしかすると環境によってはプロパティの宣言で結合演算子が使えるのでは?と思って調べたのですがわからず、上記のような方法で対応しました。
    お役に立てれば幸いです^^

  • [CakePHP2][Bad]Filebinderプラグインを別のプラグインの中のモデルに使用する方法 | HappyQuality
    Pingbacked on

    [...] 参考:CakePHPの超便利なファイルアップロードプラグイン、FileBinderプラグインの使い方をまとめてみた。 ? INSPIRE TECH [...]

  • cakePHP 2.x 画像アップロードプラグイン”upload”の使い方 | Workabroad.jp
    Pingbacked on

    [...] ロ考えてやめました。画像系って一回組み込むと変えたくないからちょっと慎重になる。 CakePHPの超便利なファイルアップロードプラグイン、FileBinderプラグインの使い方をまとめてみた。 [...]

  • cakePHP 2.3 ファイルアップロード - FileBinderプラグイン » endo blog
    Pingbacked on

    [...] 参考:CakePHPの超便利なファイルアップロードプラグイン、FileBinderプラグインの使い方をまとめてみた。 [...]

  • 使えそうなCakePHPプラグインリンク集 | asklife
    Pingbacked on

    [...]http://inspire-tech.jp/2011/07……er_plugin/ [...]

  • cakePHP 2.3 ファイルアップロード - FileBinderプラグイン - endo blog
    Pingbacked on

    [...] FileBuinderの参考: CakePHPの超便利なファイルアップロードプラグイン、FileBinderプラグインの使い方をまとめてみた。 FileBinderプラグイン [...]

  • [CakePHP]Firebinderプラグインでサムネイル作成(Imagebinderプラグインを併用) | HappyQuality
    Pingbacked on

    […] […]

  • FileBinderの設定 | Logicky Blog
    Pingbacked on

    […] 引用:CakePHPの超便利なファイルアップロードプラグイン、FileBinderプラグインの使い方をまとめてみた。 […]

  • cakePHP 2.3 ファイルアップロード - FileBinderプラグイン - Logicky Blog
    Pingbacked on

    […] FileBuinderの参考: CakePHPの超便利なファイルアップロードプラグイン、FileBinderプラグインの使い方をまとめてみた。 FileBinderプラグイン […]

  • Elderee
    Commented on

    discreet cialis meds 40, an approximate two fold decrease in marijuana LR 0

  • Scuby
    Commented on

    Confira todos os palpites brasileirГЈo aqui de todas as rodada do brasileirГЈo, de todo os dias da semana (segunda-feira, terГ§a-feira, quarta-feira, quinta-feira, sexta-feira, sГЎbado e domingo). Nesta terça-feira (25), os jogos de hoje destacam o duelo que pode definir o campeão do Brasileirão Série A. Além disso, tem oito partidas da Champions League. Oferta exclusiva Parimatch : BГґnus 2500 UAH EnciclopГ©dia Os cookies nos ajudam a administrar este site. Ao usar nosso site, vocГЄ concorda com nosso uso de cookies. PolГ­tica de privacidade O Brasileirão Série A 2022 está na sua reta final. A 32ª rodada terá início no próximo sábado (15), com três partidas abrindo a jornada 32 da Série A.
    http://www.momexclusive.com/communities-2/moms/resultados-da-champions-hoje/
    >Aplicativo de resultados do LANCE! estГЎ disponГ­vel na versГЈo iOS VocГЄ aceita a coleta destes cookies para o melhor desempenho do site e para finalidades de pesquisas analГ­ticas? CONFIRA TODOS OS RESULTADOS DESTE DOMINGO (31)CAMPEONATO BRASILEIRO DA SÉRIE A prуximos jogos do Corinthians A equipe com melhor ataque da BrasileirГЈo SГ©rie A Г© o Palmeiras, com 66 gols marcados em 38 jogos. RODADA 21вљЅ 08.08. 20:00 Coritiba 1 x 2 SantosвљЅ 07.08. 19:00 AtlГ©tico-MG 2 x 3 Athletico-PRвљЅ 07.08. 18:00 Fortaleza 3 x 0 InternacionalвљЅ 07.08. 16:00 Fluminense 1 x 0 CuiabГЎвљЅ 07.08. 16:00 Palmeiras 3 x 0 GoiГЎsвљЅ 06.08. 20:30 SГЈo Paulo 0 x 2 FlamengoвљЅ 06.08. 19:00 AtlГ©tico-GO 2 x 1 BragantinoвљЅ 06.08. 19:00 AvaГ­ 1 x 1 CorinthiansвљЅ 06.08. 16:30 Botafogo 1 x 1 CearГЎвљЅ 06.08. 16:30 Juventude 0 x 1 AmГ©rica-MG

  • ルイ・ヴィトンスーパーコピー
    Commented on

    ブランドコピーならにお任せ!
    弊店のロレックスブランドコピーは2年無料保証になります。
    ご入金が確認できてから1週間でお届け致します。
    ロレックスコピー時計などを購入したい方はこちらへ。
    ロレックスブランドコピー時計通販、N級品、全て新品、高い品質、激安、送料無料。
    ルイ・ヴィトンスーパーコピーhttps://www.taka78.com/products-2546.html

  • Ernestartew
    Commented on

    Incredible quite a lot of good facts.
    pay someone to write an essay for youbuy argumentative essays online

  • Hectorbaw
    Commented on

    Wonderful write ups. Thanks a lot.
    website to write essays for youdo my essay review what should i write my college essay on quiz

  • Scottrek
    Commented on

    Great stuff. Kudos!
    online casino gamingballys casino online real money online casino no deposit bonus

  • Nathancot
    Commented on

    Awesome stuff. With thanks.
    essay for meessay wroter write my essay for me fast

  • Sleri
    Commented on

    When you play free casino games online, any winnings generated are subject to the wagering terms and conditions, as set out by the online casino. All free casino games include information on playthrough requirements. There is nothing quite like the excitement of possibly winning big just by betting on your own luck. With real money slots, that is exactly what you are doing. In the real world, your chance of hitting a big slot machine jackpot win is 1 in 262,144 (yikes). But who really cares about the odds when you’re playing free casino games that pay real money? Slot options include many popular live casino titles that you can find online, too. Many slot studios make games exclusively for online casinos, too. Cashman Casino – Free Slots Machines & Vegas Games Rather than earning free spins by getting diamonds, Zombie Casino Slots instead lets you play carnival style mini-games when you earn bonus chests. In between spins you’ll do everything from the classic coin drop game to picking tarot cards.
    http://www.rentalchunha.co.kr/bbs/board.php?bo_table=free&wr_id=165356
    Willy Wonka Slots Free Casino Mod Apk: is your lucky ticket to FREE authentic, casino-style slot machine games and the iconic cast of Willy Wonka and the Chocolate Factory! #willy coins, #golden eggs, #code for, #chips wonka, #generator no survey, #how to enter cheat in, #games online website, #bonuses, #codes, #play, #slot freebies bonus, #chips, #premium vouchers, #offers redemption, #mod apk generator Jackpot Master Slots Free Coin, Jackpot Master Slots Free Coins 2023-2024, Jackpot Master Slots is a popular online game and … Jackpot Master Slots Free Coin, Jackpot Master Slots Free Coins 2023-2024, Jackpot Master Slots is a popular online game and … The best way to get Willy Wonka coins is through our special online generator. If it sounds confusing, don’t worry. We will explain the entire process in detail, so you’ll know what to do. After that, you’ll be able to use the Willy Wonka Slots free coins generator anytime you want, and the process will feel easy and effortless. Using the generator will help you win all the bonuses, free spins, and other valuable resources, so be sure to give it a try.

コメント・ピンバックは現在受け付けていません。


[8]ページ先頭

©2009-2025 Movatter.jp