この記事を読むのに必要な時間は約 26 分です。
CakePHP で、画像のアップロードやサムネイル作成までを簡単に行える、Upload プラグインについて、使い方をご紹介したいと思います。
今回は、View や Controller の変更・作成について解説したいと思います。
[pn-box color=”lgray”]Upload プラグインの動作の解説等は以下をご覧下さい。
→ CakePHP Upload プラグインの動作解説 : 画像のアップロードからサムネイル作成まで手軽にできる CakePHP Uploadプラグイン
導入方法や DB 変更、Model の変更・作成については以下をご覧下さい。
→ CakePHP Upload プラグインの使い方 (1) 導入・DB, Model 変更
Behavior の設定は、次回扱いたいと思います。
しっかり理解する CakePHP Upload プラグインの使い方 (3) Behavior の設定
これまでは、各項毎に、既存テーブルへのカラム追加 / 新規テーブル追加 を分けていましたが、今回は、先にそれぞれを分ける構成になります。
それぞれの例については、前回記事 2-1. 既存テーブルへのカラム追加、もしくは、2-2. 新規テーブル追加、2-3. 複数カラムを利用する場合 などをご覧下さい。
1. 既存テーブルにカラム追加した場合
1-0. 例のおさらい
例としては、以下のように、users テーブルに photo, photo_dir のカラムを追加した場合です。
CREATE table users ( `id` int(10) unsigned NOT NULL auto_increment, `username` varchar(20) NOT NULL, `photo` varchar(255) DEFAULT NULL, `photo_dir` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) );
1-1. (View) アップロード用の Form の用意
ファイルをアップロードするために、Form を用意します。
今回は、users テーブルにカラム photo, photo_dir を追加した場合のため、例えば app/View/Users/add.ctp に以下を用意します。
<?php echo $this->Form->create('User', array('type' => 'file')); ?> <?php echo $this->Form->input('User.username'); ?> <?php echo $this->Form->input('User.photo', array('type' => 'file')); ?> <?php echo $this->Form->input('User.photo_dir', array('type' => 'hidden')); ?> <?php echo $this->Form->end(); ?>
ポイントは、以下の点です。
- 1 行目 Form->create に、 type : file を指定します。これで、ファイルアップロード用の Form に切り替わります。忘れがちですので、ご注意下さい。
- 3 行目 Behavior で指定したファイル名用のカラムに対応する input で、type : file を指定します。これでファイル選択用のボタンに切り替わります。
4 行目 の photo_dir が hidden で必要なのか少々不明です。無くても動作するのかも知れませんが、document に載っているので、入れておいた方が無難かと思います。
Form Helper を利用していますので、UsersController で Helper の指定もお忘れなく。
<?php class UsersController extends AppController{ ... public $helpers = array( "Form", ); ... } ?>
あとは、UserModel の save() が動作する際に、Behavior の設定によって、自動的に photo にファイル名が、photo_dir にディレクトリ名が登録されます。Controller の変更は不要です。
Update する時などについては、まだ試していないため、省略させていただきます… 。
1-2. 保存用ディレクトリベースの用意
保存用ディレクトリのベースを用意しておきます。
デフォルトでは、app/webroot/files/モデル名/カラム名 になります。したがって、例であれば、以下のパスになります。これを web から書き込み可能なパーミションで用意しておきます。
app/webroot/files/user/photo
※ 実際に格納されるのは、Behavior の設定に従い、上記ディレクトリ配下に {photo_dir:ディレクトリ名}/{photo:ファイル名} の形で登録されます。例えば、1/FILE.jpg、2/FILE.jpg … のように格納されます。詳細は、以下の記事をご覧下さい。
→ しっかり理解する CakePHP Upload プラグインの使い方 (3) Behavior の設定
1-3. 画像の表示
画像を表示する際には、例えば以下のようすれば良いかと思います。
$base = $this->Html->url( "/files/user/photo/" ); $this->Html->image( $base . $user["photo_dir"] . "/" . $user["photo"] );[pn-box color=”lgray” size=”smaller”]
2015/07/05 正しいURLの取得方法が分かったため、以前の無理矢理な相対指定を削除します。
URL の取得方法については、以下の記事で解説しています。
CakePHP 2.x で webroot の URL を取得する方法
以下のコードは以前の記述です。↓ではなく↑のコードを利用して下さい。
/* 以下は古い内容です。こちらではなく、前述の方法を利用して下さい。 $this->Html->image("../files/user/photo/" . $user["photo_dir"] . "/" . $user["photo"] ); */
これで、<img src=”/x(CakeWebRoot)x/img/../files/user/photo/1/IMAGE01.jpg のように出力されます。
Html Helper の image() は、app/webroot/img からの相対パス指定になるため、美しくないですが、”../” をつけて webroot に移動させています。
2. 新規テーブル追加の場合
2-0. 例のおさらい
例としては、以下のように、attachments テーブルを用意し、 attachment カラムに Upload Behavior を適用した場合です。
CREATE table attachments ( `id` int(10) unsigned NOT NULL auto_increment, `model` varchar(20) NOT NULL, `foreign_key` int(11) NOT NULL, `name` varchar(32) NOT NULL, `attachment` varchar(255) NOT NULL, `dir` varchar(255) DEFAULT NULL, `type` varchar(255) DEFAULT NULL, `size` int(11) DEFAULT 0, `active` tinyint(1) DEFAULT 1, PRIMARY KEY (`id`) );
リレーションは以下を指定しています。
- Attachment : belongsTo : Post
- Attachment : belongsTo : Message
- Post : hasMany : Image (Attachment)
- Message : hasMany : Video (Attachment)
() は、エイリアス(=別名) を使って登録しています。
2-1. (View) アップロード用 Form の用意
新規テーブル利用であれば、アップロードおよびレコード登録するには、複数の方法が考えられます。
- Attachment モデル専用の登録を行う Form を用意
- 参照先 (Post、Message) を登録する時に、saveAll() を利用して、まとめて登録
実際の利用場面では、b. のケースが多いかと思います。Post を登録する際に、画像も合わせてアップロードする、というのが自然かと思います。
2-1-a. Attachment モデル専用の登録を行う Form を用意する場合
例えば app/View/Attachments/add.ctp で以下のような Form を用意すれば、とりあえず登録することはできます。
<?php echo $this->Form->create('Attachment', array('type' => 'file')); ?> <?php echo $this->Form->input('model'); ?> <?php echo $this->Form->input('foreign_key'); ?> <?php echo $this->Form->input('attachment', array('type' => 'file')); ?> <?php echo $this->Form->input('dir', array('type' => 'hidden')); ?> <?php echo $this->Form->input('active'); ?> <?php echo $this->Form->end(); ?>
「1. 既存テーブルへのカラム追加」の場合と同様です。
model 名や foreign_key がただのテキスト入力になるため、必要に応じてチェック追加などした方が良いかと思います。
2-1-b. 参照先 (Post、Message) を登録する時に、saveAll() を利用してまとめて登録する場合
例えば、app/View/Posts/add.ctp で、以下のような Form を用意します。
<?php echo $this->Form->create('Post', array('type' => 'file')); echo $this->Form->input('Image.0.attachment', array('type' => 'file', 'label' => 'Image')); echo $this->Form->input('Image.0.model', array('type' => 'hidden', 'value' => 'Post')); /* … その他 Post のフィールド用 Form (省略) … */ echo $this->Form->end(__('Add')); ?>
ポイントは、以下の通りです。
- 2 行目 Form->create に type : file を指定します。
- 3 行目 Behavior を適用する attachment の input にも type : file を指定します。
- 3-4 行目 第一引数を “Image.0.カラム名” の形にします。
- “Image” は、Post モデルで hasMany を登録した際のエイリアス名に合わせます。
( Post -> hasMany -> Attachment であれば、Image ではなく Attachment を指定します ) - “0” は固定です。これで Controller は $this->request->data[“Image”][0][カラム名] … といった感じで受け取れ、PostModel->saveAll() で扱えます。
- もし、同時に n件 (Attachment を nレコード) 登録するならば、Image.1.カラム名, Image.2.カラム名 … といった感じで、並べて追加しておけば可能だと思います。
- “Image” は、Post モデルで hasMany を登録した際のエイリアス名に合わせます。
2-2. (Controller) save() メソッドの修正
2-2-a. Attachment モデル専用の登録を行う Form を用意する場合
特別な変更は不要です。普通に AttachmentsController で、
$this->Attachment->save( $this->request->data );
などで登録可能です。
2-2-b. 参照先 (Post、Message) を登録する時に、saveAll() を利用してまとめて登録する場合
app/Controller/PostsController.php を修正します。
$this->Post->save($this->request->data); ↓ $this->Post->saveAll($this->request->data);
saveAll は、(正しい形で入っていれば) リレーションの先のテーブルもまとめて登録してくれます。便利ですが、問題発生時の切り分けが大変にはなりますので、ご注意下さい。
2-3. 保存用ディレクトリの用意
この辺りは、1-2. と同じです。
保存用ディレクトリのベースを用意しておきます。
app/webroot/files/モデル名/カラム名 がデフォルトですので、以下のパスになります。これを web から書き込み可能なパーミションで用意しておきます。
app/webroot/files/attachment/attachment
※ 実際に格納されるのは、Behavior の設定に従い、上記ディレクトリ配下に {dir:ディレクトリ名}/{name:ファイル名} の形で登録されます。例えば、1/FILE.jpg、2/FILE.jpg … のように格納されます。詳細は、以下の記事をご覧下さい。
→ しっかり理解する CakePHP Upload プラグインの使い方 (3) Behavior の設定
2-4. 画像の表示
画像を表示する際には、例えば以下のようすれば良いかと思います。
$base = $this->Html->url( "/files/attachment/attachment/" ); $this->Html->image( $base . $post["Image"][$i]["dir"] . "/" . $post["Image"][$i]["attachment"] );
$i は、1:多 で複数登録を想定しているためです。DB から取得された内容に合わせて、$post[“Image”] 等のループで回して下さい。 画像が 1 件のみ紐づくのであれば、0 固定で出来るかと思います。
[pn-box color=”lgray” size=”smaller”]
2015/07/05 正しいURLの取得方法が分かったため、以前の無理矢理な相対指定を削除します。
URL の取得方法については、以下の記事で解説しています。
CakePHP 2.x で webroot の URL を取得する方法
以下のコードは以前の記述です。↓ではなく↑のコードを利用して下さい。
/* 以下は古い記述です。↑の記述を利用して下さい。 $this->Html->image("../files/attachment/attachment/" . $post["Image"][$i]["dir"] . "/" . $post["Image"][$i]["attachment"] ); */
3. 複数カラムを追加した場合
3-0. 例のおさらい
users テーブルに icon, bg, dir カラムを追加した場合です。
CREATE table users ( `id` int(10) unsigned NOT NULL auto_increment, `username` varchar(20) NOT NULL, `icon` varchar(255) DEFAULT NULL, `bg` varchar(255) DEFAULT NULL, `dir` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) );
3-1. (View) アップロード用 Form の用意
ファイルをアップロードするために、Form を用意します。
今回は、users テーブルにカラム icon, bg, dir を追加した場合のため、例えば app/View/Users/add.ctp に以下を用意します。
<?php echo $this->Form->create('User', array('type' => 'file')); ?> <?php echo $this->Form->input('username'); ?> <?php echo $this->Form->input('icon', array('type' => 'file')); ?> <?php echo $this->Form->input('bg', array('type' => 'file')); ?> <?php echo $this->Form->input('dir', array('type' => 'hidden')); ?> <?php echo $this->Form->end(); ?>
ポイントは、以下の点です。
- 2,3 行目 type : file な input を icon 用、bg 用、それぞれに用意します。
- 5 行目 dir 用の hidden な input は 1 つのみで OK です。
3-2. 保存用ディレクトリの用意
保存用ディレクトリのベースを用意しておきます。
デフォルトでは、app/webroot/files/モデル名/カラム名 になります。したがって、例であれば、以下のパスになります。これを web から書き込み可能なパーミションで用意しておきます。
app/webroot/files/user/icon app/webroot/files/user/bg
※ 実際に格納されるのは、Behavior の設定に従い、上記ディレクトリ配下に {dir:ディレクトリ名}/{icon、bg :ファイル名} の形で登録されます。例えば、以下のようにファイルが生成されます。
- 1 件目 : icon/1/icon-file.jpg・bg/1/bg-file.jpg
- 2 件目 : icon/2/icon-file.jpg・bg/2/bg-file.jpg
詳細は、以下の記事をご覧下さい。
→ しっかり理解する CakePHP Upload プラグインの使い方 (3) Behavior の設定
3-3. 画像の表示
画像を表示する際には、例えば以下のようすれば良いかと思います。
$base = $this->Html->url( "/files/user/" ); $this->Html->image($base . "icon/" . $user["dir"] . "/" . $user["icon"] ); $this->Html->image($base . "bg/" . $user["dir"] . "/" . $user["bg"] );
[pn-box color=”lgray” size=”smaller”]
2015/07/05 正しいURLの取得方法が分かったため、以前の無理矢理な相対指定を削除します。
URL の取得方法については、以下の記事で解説しています。
CakePHP 2.x で webroot の URL を取得する方法
以下のコードは以前の記述です。↓ではなく↑のコードを利用して下さい。
/* 以下は古い記述です。↑の記述を利用して下さい。 $this->Html->image("../files/user/icon/" . $user["dir"] . "/" . $user["icon"] ); $this->Html->image("../files/user/bg/" . $user["dir"] . "/" . $user["bg"] ); */
ひとこと
今回で、実際のアップロードまで出来るようになったかと思います。
次回は、Upload Behavior の設定について扱いたいと思います。
楽しみにお待ちいただければ幸いです。
[pn-box color=”lgray”]次の記事は、以下になります。良かったら以下もご覧下さい。
しっかり理解する CakePHP Upload プラグインの使い方 (3) Behavior の設定
今回は以上です。
[pn-amzn-cakephp]