2015年8月1日 星期六

Laravel5 file upload 上傳檔案範例

我把 controller 的範例分兩個來看,一個是多檔上傳,一個是單檔上傳,也不是說寫得很好,但至少還可以 work。

多檔上傳的範例:
另外因為是 json 回傳,所以 ajax 的部分我就不說明了。
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Media;
use Validator;
use Request;
use Response;
//use Uuid;
class MediaController extends Controller
{
// 省略其他 method
public function store()
{
$files = Request::file('photo');
//print_r($files);
// 儲存成功的資料
$medias = [];
// 儲存失敗的資料
$errors = [];
foreach($files as $file) {
$rules = ['photo' => 'required|mimes:jpeg,bmp,png,jpg'];
$validator = Validator::make(['photo'=> $file], $rules);
if ($validator->fails()) {
array_push($errors, $validator->messages());
} else {
if ($file->isValid())
{
$media = new Media;
//設定要儲存的路徑
$destinationPath = base_path() . '/public/uploads';
// getting image extension
$extension = $file->getClientOriginalExtension();
// do other thing~... ex: resize, crop....
// 如果你有裝 uuid 的話 renameing image
// $fileName = Uuid::generate(4) . '_store_.' . $extension;
$fileName = $file->getClientOriginalName() . '.' . $extension;
// move file to dest
$file->move($destinationPath, $fileName);
// save data
$media->src = $fileName;
$media->save();
array_push($medias, $media);
}
}
}
//response success
return Response::json(
array(
'data' => $medias,
'error' => $errors
), 200);
}
}


單檔上傳的範例:
<?php
use App\Http\Controllers\Controller;
use App\Media;
use Validator;
use Request;
use Response;
use Uuid;
class MediaController extends Controller
{
// 省略其他 method
public function store()
{
$request = Request::all();
//print_r($request);
$rules = ['photo' => 'required|mimes:jpeg,bmp,png,jpg'];
$validator = Validator::make($request, $rules);
if ($validator->fails()) {
// json error
return $validator->messages()->toJson();
} else {
if (Request::hasFile('photo')) {
if (Request::file('photo')->isValid())
{
$media = new Media;
$destinationPath = base_path() . '/public/uploads';
// getting image extension
$extension = Request::file('photo')->getClientOriginalExtension();
// 如果你有裝 uuid 的話 renameing image
// 沒有則是可以自己 random 檔名,或沿用舊檔名
$fileName = Uuid::generate(4) . '_store_.' . $extension;
// move file to dest
Request::file('photo')->move($destinationPath, $fileName);
// save data
$media->src = $fileName;
$media->save();
//response success
return Response::json(array('data' => $media), 200);
}
}
}
}
}

另外我也描述一下 view 的 form:
{!! Form::open(array(
'route' => 'media.store',
'class' => 'form-horizontal',
'id' => 'media-frm',
'method'=>'POST',
'files'=>'true' ))
!!}
<!--單檔上傳請用這個 Form::file -->
{!! Form::file('photo') !!}
<!--多檔上傳請用這個 Form::file -->
{!! Form::file('photo[]', array('multiple'=>true)) !!}
<input type="submit" value="上傳"/>
{!! Form::close() !!}

範例裡面有兩個 Form::file,請選擇是用哪一種,一個是 photo,另一個是 photo[]。

你還可以多注意的事情
* 檔名的建立方式我通常偏好 uuid,這部分就是依個人喜好。
* 圖片的 crop, resize 在這個範例並沒有做,你也可以自己串。
* 如果你不是用 Form:: 的方式在 view 建立你的 <form> 等等標籤,那麼務必要記得 form 的這個 enctype="multipart/form-data" (在這個範例是透過 'files'=>'true' 屬性產生)屬性一定要有,否則你永遠沒有東西可以上傳
* 這邊沒有做 javascript ajax 的範例,所以如果你是沿用這個 sample,當然送出之後會接看到 json 格式的頁面,所以也是要自己把這段串起來,這邊我是為了方便,才先用 form submit。

參考
How To Create File Upload With Laravel By clivern On April 10, 2014
webpatser/laravel-uuid

2 則留言:

  1. 多檔上傳的controller 不也可以只接收一個檔案嗎?
    這樣為何要多寫一個只能接受單檔, 是因為設計的時候就是只允許單檔嗎?

    回覆刪除
    回覆
    1. 可能吧 我只是把所有的情況寫出來~

      刪除

若你看的文章,時間太久遠的問題就別問了,因為我應該也忘了... XD

Vue multiselect set autofocus and tinymce set autofocus

要在畫面一進來 focus multiselect 的方式: 參考: https://jsfiddle.net/shentao/mnphdt2g/ 主要就是在 multiselect 的 tag 加上 ref (例如: my_multiselect), 另外在 mounted...