Fájlfeltöltés
Előbb utóbb szükségünk lesz arra, hogy a felhasználó egy képet/fájlt tudjon feltölteni, mint pl.: Profilkép, vagy ha egy piacteret készítenénk akkor a termék fotóit, dokumentumait
Az alábbi példában egy kép feltöltését fogom megmutatni:
Hozzuk létre a szükséges route-kat (web.php)
Értelemszerűen az egyik útvonal azért felel, hogy megjelenítse a form-ot a második, pedig azért, hogy feldolgozza.
Route::get('/fajlfeltoltes',[ImageController::class,'create'])->name('fajl');
Route::post('/fajlfeltoltes', [ImageController::class, 'store'])->name('image.upload');
Szükségünk lesz egy adatbázis táblára amiben tároljuk majd a kép elérési útját. Készítsük el a migrációt és a modellt is hozzá.
php artisan make:migration create_images
database/migrations/...create_images.php
....
public function up(): void
{
Schema::create('images', function (Blueprint $table) {
$table->id('image_id');
$table->string('file_path');
$table->timestamps();
});
}
....
php artisan make:model Image
app/Http/Models/Image.php
....
class Image extends Model
{
public $table = "images";
public $primaryKey = "image_id";
}
....
Készítsük el a form-ot. Figyeljünk rá, hogy a form metódusának mindenképpen POST-nak kell lennie, és az enctype="multipart/form-data" attribútumot is hozzá kell adni.
resources/views/fajlForm.blade.php
...
@if(session('success'))
<p style="color: green;">{{ session('success') }}</p>
@endif
@if($errors->any())
<p style="color: red;">{{ $errors->first() }}</p>
@endif
<form method="POST" enctype="multipart/form-data">
@csrf
<input type="file" name="image" id="image">
<br>
<button type="submit" class="btn btn-dark mt-3">Feltöltés</button>
</form>
...
Hozzunk létre egy controllert (vagy akár használjuk a már meglévőt, attól függően, hogy mihez kell a kép):
php artisan make:controller ImageController
app/Http/Controllers/ImageController.php
...
use App\Models\Image;
class FajlController extends Controller
{
public function create(){
return view('fajlForm');
}
public function store(Request $request){
$request->validate([
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:5120',
],
[
'image.required' => "A kép megadása kötelező",
"image.image" => "Képet kell megadnod",
"image.mimes" => "A kép lehetséges típusai: jpeg,png,gif,svg",
"image.max" => "Maximum 5 Mb lehet a kép mérete"
]);
if ($request->file('image')) {
$filePath = $request->file('image')->store('kepek', 'public');
$image = new Image();
$image->file_path = $filePath;
$image->save();
return back()->with('success', 'A kép sikeresen feltöltve!');
}
return back()->withErrors(['image' => 'A feltöltés sikertelen volt.']);
}
}
...
Egy kis magyarázat a fenti kódhoz
- $request->file('image')->store('kepek', 'public'); Az image nevű input fájlt feltölti a storage/app/public/kepek nevű mappába (akkor is ha az nem létezne). Ez azt jelenti, hogy elérhető lesz a weboldaladon keresztül. Ha a public szó helyére local-t írsz akkor azt a weboldal látogatója nem fogja elérni.
- if ($request->file('image')) A fájl tényleges feltöltésének ellenőrzésére szolgál. Bár átmegy egy validációs folyamaton előtte, az csak azt vizsgálja, hogy fájl típusa stb. megfelelő-e. Ha nem sikerül a fájl feltöltés visszairányítjuk a formra, egy hibaüzenettel: return back()->withErrors(['image' => 'A feltöltés sikertelen volt.']);
Utolsó és az egyik legfontosabb lépés, hogy hozzuk létre a szimbolikus linket a feltöltött fájlokhoz.
Mit jelent ez pontosan? Laravelben az alapértelmezett fájltárolási hely a storage/app/public mappa. Azonban a weboldal közvetlenül nem fér hozzá a storage/ mappa tartalmához, mert az nem a public/ mappán belül van. Gondoljunk rá úgy, mintha egy parancsikont hoznánk létre a public mappában.
php artisan storage:link