In deze paragraaf zal stap voor stap besproken worden hoe je een afbeelding kan uploaden naar de server en dit kan opslaan in de database. Hiervoor gebruiken we de case: de functionaliteit om een profielfoto toe te voegen aan een user account.
Maak een view waarin je het upload formulier kan plaatsen. Bv profielfoto-create.view.php
In profielfoto-create.view.php komt het formulier te staan.
In het formulier :
<?php view("parts/header", ['title' => 'profielfoto']); view("parts/navigatie-menu"); ?> <?php if (auth()): //dit wil je alleen kunnen als je ingelogd bent ?> <div class="m-10"> <form action="/profielfoto-store" method="post" enctype="multipart/form-data"> <?= csrf() ?> Selecteer een profielfoto:<br> <input type="file" name="foto" id="foto" class="border border-1 rounded-md px-2 py-1"> <!-- om eventuele errors te tonen --> <?php if (errors('foto')): ?> <p class="text-red-500 text-sm my-2"><?= errors('foto') ?></p> <?php endif; ?> <br> <input type="submit" value="Upload profielfoto" name="submit" class="border border-1 rounded-md px-2 py-1 hover:bg-gray-100 cursor-pointer shadow-sm mt-2"> </form> </div> <?php endif; ?> <?php view("parts/footer");
Belangrijk is dat je aan je form enctype="multipart/form-data" toevoegd. Dit maakt het mogelijk om bestanden te versturen.
Daarna kan je eenvoudig de <input type="file" .. gebruiken als veld waar je de afbeelding kan selecteren.
Als action hebben we /profielfoto dus daar moeten we een route voor aanmaken. Eén voor de view en één voor het opslaan van de foto.
if (auth()) { $route->get('profielfoto-create', 'views/profielfoto-create.view.php'); $route->post('profielfoto-store','controllers/profielfoto-store.php'); }
We maken een controller: profielfoto-store.php
In dit bestand gaan we de foto toevoegen. We gaan daarbij de foto in een map plaatsen en in de database slaan we het pad op waar de foto opgeslagen is. Omdat afbeeldingen veel ruimte innemen is dit de meest praktische manier van opslaan.
De bestanden die worden geupload zijn terug te vinden in de variabele $_FILE. De naam van de profielfoto kan je met $_FILE['foto']['name'] vinden. Het framework maakt het echter makkelijk door het $request object hiervoor te gebruiken. Hierdoor is validatie ook direct mogelijk.
$request->validate([ 'foto' => 'required|image' //valide afbeelding ]);
Belangrijk is dat je een controle doet of het een afbeelding betreft. Anders zou het ook een gevaarlijk virus kunnen zijn.
Indien het een afbeelding is mag deze opgeslagen worden in de afbeeldingen map. Daarna wil je het pad naar de afbeelding toevoegen in de database. Zodat je weet bij welke gebruiker de afbeelding hoort. Vaak is het handig om de naam van de afbeelding aan te passen naar een hash, zodat het bijna onmogelijk is om dubbele namen te krijgen.
Hieronder een voorbeeldje van een controller profielfoto-store.php
<?php $request->validate([ 'foto' => 'required|image' //valide afbeelding ]); //voeg een upload directory toe aan de configuratie bv: //$uploadDirectory = config('app.uploadDirectory'); // map waarin de afbeeldingen worden opgeslagen $uploadDirectory = 'images'; // map waarin de afbeeldingen worden opgeslagen //uploadFileAs is de naam zoals wij de afbeelding uiteindelijk gaan opslaan $uploadFileAs = trim($uploadDirectory, '/') . '/' . hash('sha256', date('YmdHms') . random_int(1, 1000000)) //unieke hash . "." . strtolower(pathinfo($request->foto['name'], PATHINFO_EXTENSION)); //extensie van de afbeelding //verplaatsen naar de juiste map move_uploaded_file($request->foto["tmp_name"], $uploadFileAs); //de afbeelding is nu opgeslagen, nu gaan we deze ook in de database opslaan bij de gebruiker $db = new Database(); $db->query("UPDATE users SET profielfoto=:profielfoto WHERE id=:id", [ "profielfoto" => $uploadFileAs, "id" => user()->id, // de op dat moment ingelogde gebruiker ]); flash('success', 'Profielfoto succesvol geüpload!'); //PAS AAN: stuur de gebruiker naar de gewenste pagina redirect('/');
Als je opnieuw inlogt als gebruiker zal nu in plaats van de naam de profielfoto worden getoond in het menu.