在這篇文章中,我們將深入探討如何在 Laravel 應用程式中處理檔案上傳。我們將從前端頁面的檔案選擇到後端儲存與顯示檔案的完整流程,涵蓋從用戶選擇檔案,到將其上傳並保存在伺服器,直到如何在資料庫中儲存檔案路徑,並在頁面上顯示它們。這些步驟將有助於您瞭解如何在 Laravel 中高效地處理檔案上傳。
在 Laravel 中處理檔案上傳最簡單的方式之一是使用服務來集中管理這些操作。我們將建立一個 FilesService
類別,負責處理檔案的上傳、儲存和轉換等任務。
FilesService.php
<?php
namespace App\Services;
use ZipArchive;
use Illuminate\Support\Facades\File;
class FilesService
{
/**
* 防錯:資料夾不存在時將會自動建立資料夾,避免錯誤
* @param string $dir 要放置的資料夾名稱
*/
protected function createDir($dir)
{
if (!is_dir('upload/')) {
mkdir('upload/');
}
if (!is_dir('upload/' . $dir)) {
mkdir('upload/' . $dir);
}
}
/**
* 上傳檔案
* @param mixed $file 要轉換的File檔案
* @param string $dir 要放置的資料夾名稱
* @return object 回傳資料庫儲存的檔名及路徑
*/
public function fileUpload($file, $dir)
{
// 防錯:檔案不存在或不為檔案時回傳空字串
if (!$file || !$file->isFile()) return '';
// 防錯:資料夾不存在時將會自動建立資料夾,避免錯誤
$this->createDir($dir);
// 取得檔案的副檔名
$data = (object) [
'name' => null,
'path' => null,
];
$data->name = $file->getClientOriginalName();
$hashName = $file->hashName();
// 檔案名稱會被重新命名
$data->path = '/upload/' . $dir . '/' . $hashName;
// 移動到指定路徑
move_uploaded_file($file, public_path() . $data->path);
// 回傳 資料庫儲存用的路徑格式
return $data;
}
}
在這個 FilesService
中,我們創建了幾個主要的功能:
createDir($dir)
:檢查並創建目錄,確保儲存檔案的資料夾存在。fileUpload($file, $dir)
:處理檔案的上傳。這個方法會將檔案移動到伺服器指定的目錄,並返回檔案的路徑。接下來,在前端頁面,我們會使用 <input type="file">
元素來讓用戶選擇檔案。當用戶選擇檔案後,我們會將檔案數據傳遞到後端進行處理。
MovieCreate.vue
(前端頁面)<label for="" class="flex justify-between">
<span>電影圖片</span>
<input type="file" @input="from.img_path = $event.target.files[0]">
</label>
在這段程式碼中,@input
綁定了檔案選擇事件,將選中的檔案存儲在 from.img_path
中。我們會在 from
物件中管理電影的資料,包括名稱、影片長度、導演等。
在 Vue 組件中,我們需要創建一個 from
物件來保存用戶輸入的資料。然後,我們將這些資料發送到 Laravel 後端進行儲存。
MovieCreate.vue
(Vue.js)export default {
data() {
return {
from: {
name: '',
img_path: null,
film_length: '',
director: '',
publish_date: '',
price: 0,
},
};
},
methods: {
submit() {
router.post(route('movie-store'), this.from)
}
}
};
在 submit()
方法中,我們將使用 axios
或 Laravel 的 router.post
方法來將資料發送到後端的 movie-store
路由。
在控制器中,我們會將上傳的檔案與其他資料一起儲存。這時,我們會使用 FilesService
來處理檔案上傳的邏輯。
MovieController.php
<?php
namespace App\Http\Controllers\Backend;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Inertia\Inertia;
use App\Models\MovieList;
use App\Services\FilesService;
class MovieController extends Controller
{
public function store(Request $request)
{
$data = $request->all();
// 使用文件服務來處理檔案上傳
$files_service = new FilesService();
$path = $files_service->fileUpload($data['img_path'], 'movie');
// 儲存電影資料到資料庫
MovieList::create([
'movie_types_id' => 1,
'name' => $data['name'],
'img_path' => $path->path,
'director' => $data['director'],
'film_length' => $data['film_length'],
'publish_date' => $data['publish_date'],
'price' => $data['price'],
]);
return redirect(route('movie-index'));
}
}
在 store()
方法中,我們:
FilesService
上傳圖片並取得圖片的路徑。最後,我們可以在頁面上顯示已上傳的圖片,這樣用戶就能夠看到他們所上傳的內容。
MovieIndex.vue
<img :src="item.img_path" alt="">
這段程式碼會根據從資料庫中讀取的路徑顯示圖片。
Laravel 有一個預設的中介層會將空字串轉換為 null
,這會影響到一些資料處理。為了避免這樣的行為,我們需要註解掉這個中介層。
Kernel.php
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
// 註解這行
// \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
通過這些步驟,成功地在 Laravel 中實現了檔案上傳與處理。這不僅可以讓你輕鬆地上傳各種檔案,還能確保檔案安全地儲存到伺服器上並正確顯示在前端頁面。希望這篇文章能幫助您建立出更高效、可靠的檔案上傳系統!接下來會介紹時間參數與分頁功能。
對於這類的撰寫方式習慣嗎?歡迎多多進行良性的知識交流喔!目前是在學習階段,大家有不同看法的話歡迎進行良性的知識交流!
大家可以考慮多多分享文章和考慮訂閱沙龍方案或贊助等喔!不過請注意不要違反著作權等行為。當然決定權都在於您,不會干涉您的任何決定。
提醒,文章僅供正當的知識參考,文章不負任何責任。