Kell hozzá a Blade komponens témakör!
Ha létrehozunk egy Laravel projektet, akkor láthatjuk, hogy létezik egy tároló mappa (storage).
A Laravel alapértelmezetten ide menti el azokat a fájlokat, amit a
felhasználó feltölt majd. Amire most szükségünk lesz, illetve ahol
tárolni fogjuk az a storage / app / public /...
Megjegyzés:
a storage mappa tartalma még az alkalmazásunk naplózását végző log fájl
a logs mappájában, valamint a keretrendszerhez (framework) kapcsolódó
részek, mint például a nézetek (views) lefordított verziói. De ha
valakit érdekel a háttér, akkor megnézheti, hogy milyen kódot generált a
mi nézeteinkből a Laravel motorja: storage / framework / views mappában
az egyik véletlen karaktersorozat elnevezésű php fájlban találjuk a
nézeteink lefordított verzióit, ez lesz az, amit megkap majd a
felhasználó böngészője.
Első
lépésben nekünk most az a célunk, hogy a felhasználó által feltöltött
fájlok publikusan elérhetőek legyenek majd. Ehhez arra van szükség, hogy
a public (nyilvános hozzáférésű) mappánkat összekössük a storage / app / public mappával. Ezt egy link segítségével fogjuk megtenni. Így elérhető
lesz a felhasználó számára a feltöltött fájl. A következő parancssal lehet
megoldani a link létrehozását:
php artisan storage:link
Ha lefutott, látható, hogy a public mappában megjelent egy storage mappa link.

Mivel
általában sok képet mentünk el egy alkalmazásban, ezért mindenképp
célszerű adatbázisban tárolni a nevüket és a (merevlemezen eltárolt)
helyüket.
Hozzunk létre egy új migrációs fájlt pictures néven (vagy esetleg használd egy már létező táblád például termékeknél, márkáknál stb.).
php artisan make:migration create_pictures_table
Három darab új oszlopot kell hozzáadni, ahogy feljebb is említettem, és ha megvan, mehet is a migrálás.
public function up()
{
Schema::create('pictures', function (Blueprint $table) {
$table->id();
$table->string('name')->nullable();
$table->string('location')->nullable();
$table->foreignId('user_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
$table->timestamps();
});
}
A név és a hely
oszlopokról már írtam, de vegyük észre, hogy itt van egy külső kulcs is,
amivel hozzákötjük a profilképet a bejelentkezett felhasználóhoz (ha
pedig a felhasználó módosul vagy törlődik, akkor a profilképe is
hasonlóan "cselekszik", lásd a cascade paramétereket).
Migráljuk az adatbázisunkba a táblát:
php artisan migrate
Mivel adattábláról van szó, mindenképp kelleni fog egy modell osztály is, hozzuk is létre Picture néven.
php artisan make:model Picture
Ezen belül meg hivatkozzunk arra a két mezőre, amiket a migrációs fájlban definiáltunk:
protected $fillable = [
'name',
'location'
];
A teszt miatt létrehoztam egy új Controller-t is (de ez nem feltétlenül lenne kötelező).
php artisan make:controller PictureUploaderController
Ha
ez megvan, akkor létrehozok három új útvonalat a web.php-ban és azon belül a middleware('auth') részben (ahol a többi profile útvonal is van már - ezáltal csak bejelentkezett felhasználók tudják majd elérni ezeket az új útvonalakat): az
egyik a űrlapra fog vezetni (kvázi "create" Controller metódus), míg a
másik az adatok eltárolására szolgál (kvázi "store" Controller metódus),
és lesz még egy, ami a képet fogja megmutatni (kvázi "show" Controller
metódus).
Route::get("/profile/picture/create" , [PictureUploaderController::class, 'create'])->name('profilepic.create');
Route::post("/profile/picture" , [PictureUploaderController::class, 'store'])->name('profilepic.store');
Route::get("/profile/picture" , [PictureUploaderController::class, 'show'])->name('profilepic.show');
A web.php tetején importáljuk be a PictureUploaderController fájlt.
Majd kezdjük a "create" útvonallal és annak a Controller metódusával, ami majd egy űrlapra fog vezetni minket.
public function create()
{
return view('profile.picture.create');
}
Írjuk meg az űrlapot, ahhoz viszont hozzuk létre a resources / views / profile / picture / create.blade.php fájlt (ehhez persze szükség van a picture új mappára is).
A form tagbe nem hiányozhat a enctype="multipart/form-data", mert adatot mozgatunk.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Profilkép feltöltése</title>
</head>
<body>
<form action="/profile/picture" method="POST" enctype="multipart/form-data">
@csrf
<label for="file">Profilkép kiválasztása:</label>
<input type="file" id="file" name="file">
</form>
</body>
</html>
Hozzuk létre a store() metódus magját is:
$request->validate([
'file' => 'required|mimes:jpg,png|max:2048'
]);
$save = new Picture();
if ($request->file()) {
$renames = time() . '_' . rand() . $request->file->getClientOriginalName();
$picture = $request->file('file')->storeAs( 'kepfeltolt' ,$renames , 'public');
$save->picturename = $renames;
$save->filelocation = 'storage/' . $picture;
$save->save();
}
return redirect("/");
Már
csak egy dolgunk van hátra, a fájlok lekérése. Még a web.php-nál át
lett írva a welcome nézet, hogy a controllerben le tudjunk kérni az
adatokat, mindenképp useolni kell a DB-t.
public function welcome()
{
$keplekeses = DB::table("pictures")->select("*")->get();
return view('welcome', compact("keplekeres"));
}
Ha ez megvan akkor utolsó lépésként jelenítsük meg a feltöltött képeket:
<html lang="hu">
<head>
<title>Fő oldal</title>
</head>
<body>
@foreach ($keplekeres as $kep)
<img src="{{$kep->filelocation}}" alt="">
@endforeach
</body>
</html>