Laravel 12 Tippek & Trükkök Magyarul

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