アップロードしてサーバーに保存した画像ファイルを表示するには、いくつか方法があります。

前回のように、誰もが見れるパブリックな場所(public/images/product)にファイルを保存したなら、

namespace App;

use Illuminate\Database\Eloquent\Model;

class ProductImage extends Model
{
	protected $table = 'product_image';
	protected $primaryKey = 'product_image_id';
	public $incrementing = true;
	public $timestamps = true;

	protected $fillable = [
		'product_id', 'mime'
	];

	protected $baseUri = 'images/product';

	public function getUrlAttribute()
	{
		return url($this->baseUri, $this->filename());
	}

	public function storeImage($file)
	{
		$file->move(public_path($this->baseUri), $this->filename());
	}

	public function filename()
	{
		$ext = 'jpg';

		switch($this->mime)
		{
			case 'image/jpeg':
			case 'image/jpg':
				$ext = "jpg";
				break;

			case 'image/png':
				$ext = "png";
				break;

			case 'image/gif':
				$ext = "gif";
				break;
		}

		return sprintf("%d.%s", $this->product_image_id, $ext);
	}

と、getUrlAttribute()のアクセサーを作成して、


@extends('user.layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">File Upload</div>
                <div class="panel-body">
                    <div class="form-group{{ $errors->has('file') ? ' has-error' : '' }}">
                        <div>
                            <form
                                method="POST"
                                action="/demo/public/admin/product/{{ $product->product_id }}/image"
                                class="dropzone"
                                id="imageUpload"
                                enctype="multipart/form-data">
                                {{ csrf_field() }}
                            </form>
	                    </div>
                    </div>

                    <div>
                        @foreach ($product->product_images as $image) // 1商品に対して複数の画像を表示
                            <img src="{!! $image->url !!}">
                        @endforeach
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

@section('script')

Dropzone.options.imageUpload = {
    dictDefaultMessage: 'アップロードするファイルをここへドロップしてください',
    maxFiles: 10,
    acceptedFiles: '.jpg,.jpeg,.gif,.png',
    maxFilesize: 5, // 5 MB
    init: function () {
        this.on('queuecomplete', function () { // アップロードがすべて完了したら、画面を更新してアップロードした画像を表示
            location.reload(); 
        });
    }
}
@endsection

のように、$image->urlとしてテンプレートでコールして、https://www.larajapan.com/demo/public/images/product/4.pngのような値を生成し画像をブラウザに表示します。

また、以下のEloquentのRelationshipを使用して、1商品に対して複数アップロードした画像を表示させています。


namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    protected $table = 'product';
    protected $primaryKey = 'product_id';
    public $incrementing = true;
    public $timestamps = true;

    protected $fillable = [
        'name'
    ];

    public function product_images()
    {
        return $this->hasMany('App\ProductImage');
    }

}

さて、以上は、管理者が管理画面からアップロードした画像を、同画面で表示する例ですが、ユーザー画面でも$image->urlを使用すれば、誰にでも同じ画像を見せることが可能です。

しかし、アップロードしたファイルを誰からも見えない場所に保存して、例えば、認証したユーザーしか見れないという制限が必要なら、どうしましょう?

By khino