WinRoadのLaravel4初心者講座

次世代PHPフレームワークのLaravel4を初心者向けに解説して参ります。

Winroad徒然草の管理人がお届けします
02月

ファイルをデータベースに保管する

今日は、画像ファイルやPDFファイルなどをデータベースに保管する方法をご紹介します。

  1. テーブルにバイナリデータ保管用のカラムとMIMEタイプ保管用のカラムを作成します。
  2. アップロード用のビューファイルから送信されたファイルをInput::file(‘file’)で取得します。
  3. Input::file(‘file’)->getMimeType()でMimeタイプを取得します。
  4. file_get_contents(Input::file(‘file’))で、ファイル本体を取得します。
  5. いったんデータベーステーブルに保存します。
  6. 画像ファイルを表示するために、idから取得します。
  7. バイナリデータをbase64でエンコードします。
  8. 表示用のビューファイルに、base64でエンコードした画像本体とMIMEタイプを送信します。
  9. 表示用のビューファイルのimgタグでブラウザ上に表示します。

それでは、実際に作成してみましょう。まず、最初にデータ保管用のテーブル(cabinets)を作成します。

<?php
class SetupController extends BaseController{
 public function getCabinets(){
 //cabinetsテーブルの存在確認
 if(Schema::hasTable('cabinets')){
 $data['warning']='cabinetsテーブルはあります。';
 return View::make('setup.index',$data);
 }
 //cabinetsテーブルの作成
 Schema::create('cabinets',function($table){
 $table->increments('id');
 //genbaテーブルへのリレーション用
 $table->integer('G_id')->nullable();
 //name
 $table->string('name',100)->nullable();
 //MIMEタイプの保存
 $table->string('mime',50)->nullable();
 //publicフォルダ用保存域パス
 $table->string('path',100)->nullable();
 //データ保管庫
 $table->binary('data')->nullable();
 //created_atとupdated_atの同時作成
 $table->timestamps();
 //deleted_atカラムを追加
 $table->timestamp('deleted_at')->nullable();
 });
 $data['warning']='cabinetsテーブルを作成しました。';
 return View::make('setup.index',$data);
 }
}

※データベーステーブル作成用のコントローラです。とりあえす、id,mime,dataカラムがあれば、問題ありません。

17行目:publicフォルダにファイルを保管するための保存パスの登録用カラムです。こちらに保管する方が簡単なのですが、今回は、データベースに直接フィルを保存する方法をご紹介します。

19行目:画像データやPDFファイルなどをデータベースに保管するには、データ種別をバイナリで保管します。※スキーマビルダーでは、$table->vinary()で、BLOBカラムを作成しますが、大きめのファイルも保管するのでしたら、LONGBLOBを使用した方がいいでしょう。尚、MEDIUMBLOBやLONGBLOBは、スキーマビルダーでは作成できません。

2015-02-14 22-49-13

次にモデルを作成します。モデルは特に問題はありませんが、念のために記述しておきます。

<?php
class Cabinet extends Eloquent{
 //テーブル名がcabinets(複数形)なら省略可
 protected $table='cabinets';
 //primaryKeyがidなら省略可
 protected $primaryKey='id';
 //複数代入の制限
 protected $guarded=['id','created_at','updated_at','deleted_at'];
 //ソフトデリートを使用
 protected $softDelete=true;
}

コントローラを作成します。

<?php
class CabinetController extends BaseController {
  //一覧表の表示
 public function getIndex(){
 $cabinets=Cabinet::orderBy('created_at','desc')->get();
 return View::make('cabinet.index',compact('cabinets'));
 }
 
 //アップロードデータの作成用ビュー
 public function getCreate($id=null){
 $genba=Genba::find($id);
 return View::make('cabinet.create',compact('genba'));
 }
 //ファイルのアップロード処理
 public function postCreate(){
 //ファイルのアップロード確認
 if(!Input::hasFile('file')){
 return Redirect::back()
 ->with('warning','<div class="uk-alert uk-alert-danger">ファイルがアップされていません</div>');
 }
 //アップロードファイルを取得
 $file=Input::file('file');
 //return var_dump($file);
 $name=date('YmdHis.').$file->getClientOriginalExtension();
 //新規データの作成
 $cabinet=new Cabinet;
 $cabinet->G_id=Input::get('G_id');
 $cabinet->name=Input::get('name');
 //テーブルのdataカラムにバイナリデータで保存
 $cabinet->data=file_get_contents($file);
 $cabinet->mime=$file->getMimeType();
 $cabinet->path='images/'.$name;
 $cabinet->save();
 //publicフォルダに保存
 $file->move('images/',$name);
 return Redirect::to('cabinet/view/'.$cabinet->id);
 }
 //画像ファイルをブラウザに表示する為の準備
 public function getView($id){
 //データベースに保存してあるデータを取得
 $file=Cabinet::find($id);
 //バイナリデータをbase64でエンコード
 $data['base64']=base64_encode($file->data);
 //mimeタイプを取得
 $data['mime']=$file->mime;
 return View::make('cabinet.view',$data);
 }

※31行目:file_get_contents()関数で、アップロードしたファイルを保存します。

ファイルのアップロード用ビューファイルを作成します。

@extends('uk.base')
 @section('content')
 <h3 class="menuTab">現場資料のアップデート</h3>
 {{ Session::get('warning') }}
 {{ Form::open(['files'=>'true','class'=>'uk-form uk-form-horizontal']) }}
<div class="uk-form-row">
 {{ Form::label('name','現場名',['class'=>'uk-form-label uk-form-large']) }}
 {{Form::text('name',$genba->name,['class'=>'uk-form-width-large','disabled'=>'disabled'])}}
 </div>
   <div class="uk-form-row">
 {{ Form::label('path','保存パス',['class'=>'uk-form-label']) }}
 {{Form::text('path','',['class'=>'uk-form-width-large'])}}
 </div>
 <div class="uk-form-row">
 {{ Form::label('item','ファイル種別',['class'=>'uk-form-label']) }}
 {{Form::text('item','',['class'=>'uk-form-width-large'])}}
 </div>
<div class="uk-form-row">
 {{ Form::label('file','保存ファイル',['class'=>'uk-form-label']) }}
 {{ Form::file('file') }}
 </div>
<hr>
{{ Form::hidden('name',$genba->name) }}
 {{ Form::hidden('G_id',$genba->id) }}
 {{ Form::submit('アップロード',['class'=>'uk-button uk-button-primary uk-width-1-2'] )}}
{{ Form::close() }}
 @stop

画像表示用のビューファイルです。

@extends('uk.base')
 @section('content')
 <h1>Cabinet</h1>
 <div class="uk-thumnail uk-thumnail-large">
 <img src='data:{{$mime}};base64,{{$base64}}'>
 </div>
 @stop

※<img src=”data:img/png;base64,base64_encode(バイナリデータ)”>で、データベーステーブルに保存したバイナリデータを表示します。