Laravel-tutorial voor beginners
⚡ Slimme samenvatting
Laravel is een open-source PHP MVC-framework, ontwikkeld door Taylor Otwell, waarmee je snel en overzichtelijk webapplicaties kunt bouwen. Deze tutorial legt uit wat Laravel is, hoe je het installeert met Composer en bouwt een werkende app voor het uploaden van bestanden met behulp van routes, controllers, validatie van formulierverzoeken en Blade-templates.

Wat is Laravel?
Laravel is een open-source web-MVC-framework voor PHP. Laravel is een robuust raamwerk dat de eenvoudige ontwikkeling van PHP-webapplicaties mogelijk maakt met functies zoals een modulair verpakkingssysteem met een speciale afhankelijkheidsmanager, toegang tot relationele databases en andere hulpprogramma's voor de implementatie en het onderhoud van applicaties.
Laravel is ontwikkeld door Taylor Otwell. Sinds de eerste release in juni 2011 (versie 1) is het framework steeds populairder geworden in de PHP-frameworksector van de webontwikkeling. Deze populariteit is grotendeels te danken aan de vele ontwikkelaarsvriendelijke functies die het framework standaard biedt.
Waarom Laravel?
Circa 2000, meest PHP-code was procedureel en kon worden gevonden in de vorm van ‘scripts’ die een wirwar van spaghetticode zouden bevatten. Zelfs de eenvoudigste pagina's hadden geen scheiding van zorgenEn daardoor kon een applicatie al snel uitgroeien tot een onderhoudsramp. De wereld had iets beters nodig. Daar kwam PHP versie 5 en een verscheidenheid aan PHP-frameworks om de hoek kijken, die probeerden de broodnodige structuur en betere oplossingen te bieden voor diverse problemen met webapplicaties.
Sindsdien zijn er veel frameworks uitgebracht die de weg hebben geplaveid voor de populaire frameworks die we vandaag de dag gebruiken. De top drie van vandaag zijn (naar onze mening) Zend Framework, Symfony en natuurlijk Laravel. Hoewel elk van deze frameworks is gebaseerd op vergelijkbare principes en is gericht op het oplossen van (in principe) dezelfde veelvoorkomende problemen, liggen de belangrijkste verschillen in hun implementatie. Ze hebben elk hun eigen eigenaardigheden in de manier waarop ze problemen aanpakken. Als je kijkt naar de code die door elk van hen wordt gegenereerd, zie je dat er een duidelijke scheidslijn tussen hen is. Naar onze bescheiden mening is het Laravel-framework het beste.
Meer informatie over de verschil tussen Laravel en Codeontsteker.
Hoe Laravel downloaden en installeren met Composer
Let op: Deze handleiding is geschreven voor Laravel 5.8, maar de concepten routing, controller, request en Blade blijven hetzelfde in de huidige releases. De nieuwste versie is Laravel 13 (uitgebracht in maart 2026), waarvoor PHP 8.3 of hoger vereist is, terwijl Laravel 12 PHP 8.2 vereist.
Let op: Er wordt vanuit gegaan dat PHP al op uw systeem is geïnstalleerd. Zo niet, dan kunt u lezen hoe u het kunt installeren. hier.
Composer is zowel een pakket- als afhankelijkheidsbeheerder. Om het te installeren, opent u een terminal en cd naar een nieuwe directory. Voer deze opdracht uit:
curl -Ss getcomposer.org/installer | php
De resultaten van deze opdracht zien er als volgt uit:
Let op: Voor uitgebreidere instructies over het instellen van Laravel kunt u de Laravel-documentatie raadplegen. hier.
Je ziet dat het het composer.phar-script downloadt en compileert. Dit script gebruiken we om Laravel te installeren. Hoewel er talloze manieren zijn om een nieuwe Laravel-applicatie op te zetten, doen we dit via het Laravel Composer-script. Om dit script te installeren, voer je het volgende commando uit:
composer global require laravel/installer
Wat er ongeveer zo uit zal zien:
Hiermee worden alle frameworkbestanden en alle benodigde afhankelijkheden gedownload en geïnstalleerd. De pakketten worden opgeslagen in de map `vendor`. Na het downloaden en installeren is het heel eenvoudig: voer het volgende commando uit:
laravel new uploadApp
U zult iets zien dat lijkt op het volgende resultaat:
Composer installeert alle pakketten die Laravel nodig heeft om te draaien. Dit kan een paar minuten duren, dus heb geduld. Als het klaar is, voer dan het commando `ls -al` uit om te zien wat er is geïnstalleerd.
Hier is een kort overzicht van de mappen in een veelgebruikte Laravel-applicatie:
- app/ : Dit is de bronmap waar onze applicatiecode zich bevindt. Alle controllers, beleidsregels en modellen staan in deze map.
- bootstrap/ : Bevat het opstartscript van de applicatie en een paar klassemapbestanden.
- configuratie/: Deze map bevat de configuratiebestanden van de app. Deze worden meestal niet rechtstreeks gewijzigd, maar zijn afhankelijk van de waarden die zijn ingesteld in het .env-bestand (environment-bestand) in de hoofdmap van de app.
- databank/ : Hier worden de databasebestanden opgeslagen, waaronder migraties, seeds en testfabrieken.
- openbaar/ : Een openbaar toegankelijke map met daarin de verzamelde bestanden en natuurlijk een index.php-bestand.
- bronnen/ : Bevat front-end-elementen zoals JavaScriptbestanden, taalbestanden, CSS/SASS-bestanden en alle sjablonen die in de applicatie worden gebruikt (zogenoemde blade-sjablonen).
- trajecten/ : Alle routes in de applicatie bevinden zich hierin. Er zijn verschillende "scopes" van routes, maar we zullen ons richten op de route in het web.php-bestand.
- opslag/ : Alle tijdelijke cachebestanden die door de applicatie worden gebruikt, sessiebestanden, gecompileerde weergavescripts en logbestanden.
- testen/ : Bevat testbestanden voor de applicatie, zoals unit tests en functionele tests.
- leverancier/ : Alle benodigde pakketten zijn geïnstalleerd met Composer.
Laten we nu de rest van de app bouwen en deze uitvoeren met een speciaal Artisan-commando (om onszelf de moeite te besparen van het installeren en configureren van een webserver zoals Apache of Nginx). Het .env-bestand bevat alle configuratiewaarden die de bestanden in de map /config gebruiken om de applicatie te configureren.
Applicatieontwerp: een kort overzicht van onze vereisten
In deze online Laravel-tutorial gaan we een heel eenvoudige applicatie bouwen die slechts twee dingen doet:
- bestandsuploads vanaf een webformulier afhandelen
- Toon de eerder geüploade bestanden op een andere pagina.
Voor dit project is onze applicatie alleen-schrijven, wat betekent dat de gebruiker alleen bestanden kan schrijven en de lijst met geüploade bestanden kan bekijken. Deze applicatie is zeer eenvoudig, maar dient als goede oefening om je Laravel-vaardigheden en -kennis op te bouwen. Omwille van de beknoptheid hebben we database-modellering, migraties en authenticatie weggelaten, maar in een echte applicatie zijn dit zaken die je wel wilt overwegen.
Hier is een lijst met componenten die we nodig hebben om de applicatie te laten werken zoals verwacht:
- A route Dat maakt het voor de buitenwereld (internet) mogelijk om de applicatie te gebruiken, en specificeert tevens het eindpunt waarnaar de logica voor het opslaan van het geüploade bestand verwijst.
- A controleur dat het proces van verzoek tot antwoord afhandelt.
- A sjabloon Dit scherm zal worden gebruikt om een lijst met eerder geüploade bestanden en het uploadformulier zelf weer te geven.
- A te vragen die de controller zal gebruiken om de gegevens te valideren die via het webformulier worden doorgegeven.
Wat is een route?
Een route in Laravel is in principe een eindpunt, gespecificeerd door een URI, dat fungeert als een "aanwijzer" naar een stukje functionaliteit dat door de applicatie wordt aangeboden. Meestal verwijst een route simpelweg naar een methode in een controller en bepaalt tevens welke HTTP-methoden die URI mogen benaderen. Een route hoeft echter niet altijd een controllermethode te zijn; het kan ook de uitvoering van de applicatie doorgeven aan een gedefinieerde Closure of een anonieme functie.
Waarom een route gebruiken?
Routes worden opgeslagen in bestanden onder de map /routes in de rootdirectory van het project. Standaard zijn er een paar verschillende bestanden die overeenkomen met de verschillende "zijden" van de applicatie ("zijden" komt van de hexagonale architectuurmethodologie). Deze omvatten:
- web.php: de publiekelijk toegankelijke, browsergebaseerde routes. Dit zijn de meest voorkomende routes en worden rechtstreeks door de webbrowser aangeroepen. Ze lopen via de webmiddlewaregroep en bevatten ook faciliteiten voor CSRF-bescherming (wat helpt bij de verdediging tegen kwaadaardige aanvallen via formulieren) en bevatten over het algemeen een zekere mate van "status" (hiermee bedoelen we dat ze gebruikmaken van sessies).
- api.php: routes die corresponderen met een API-groep en waarbij de API-middleware dus standaard is ingeschakeld. Deze routes zijn stateless en hebben geen sessies of geheugen dat gedeeld wordt tussen verzoeken (één verzoek deelt geen gegevens of geheugen met een ander verzoek; elk verzoek is op zichzelf staand).
- console.php: deze routes corresponderen met aangepaste Artisan-commando's die je voor je app hebt gemaakt.
- channels.php: registreert routes voor het uitzenden van evenementen.
Het belangrijkste bestand waar we ons nu mee bezig moeten houden, is het browserspecifieke bestand, web.php. Er is al één route standaard gedefinieerd, namelijk de route die je direct tegenkomt wanneer je naar de webroot van je applicatie navigeert (de webroot bevindt zich in de public-directory). We hebben drie verschillende routes nodig om onze uploadapplicatie te laten functioneren:
- /upload: dit wordt de URI van de hoofdpagina waarop ons webformulier voor het uploaden van bestanden wordt weergegeven.
- /process: dit is de plek waar het formulier op de URI /upload de ingediende gegevens naartoe stuurt (de "actie" van het formulier).
- /list: hiermee worden alle bestanden weergegeven die naar de site zijn geüpload.
Let op: Het /list-eindpunt is mogelijk niet nodig als we alle logica voor het weergeven van het uploadformulier en de lijst met bestanden op één pagina zouden willen plaatsen; we hebben ze echter voorlopig gescheiden gehouden om wat meer diepgang aan het onderwerp toe te voegen.
//inside routes/web.php
Route::get('/upload', 'UploadController@upload')->name('upload');
Route::get('/download', 'UploadController@download')->name('download');
Route::post('/process', 'UploadController@process')->name('process');
Route::get('/list', 'UploadController@list')->name('list');
In deze Laravel framework tutorial zullen we voor elke gewenste route deze expliciet vermelden in het routes-bestand web.php met behulp van een van de beschikbare HTTP-specifieke verzoekmethoden (get(), post(), put(), delete(), patch() of options()). Voor een gedetailleerde uitleg van elk van deze methoden, zie de documentatie. dit Deze methoden specificeren welke HTTP-werkwoorden toegang hebben tot de betreffende route. Als een route meerdere HTTP-werkwoorden moet accepteren (bijvoorbeeld als je één pagina gebruikt om zowel de initiële gegevens weer te geven als de gegevens van een verzonden formulier te versturen), kun je de methode `Route::any()` gebruiken.
Het tweede argument voor zowel de `Route::get()` als de `Route::post()` methode (en alle andere HTTP-gerelateerde methoden op de `Route` facade) is de naam van een specifieke controller en de methode in die controller die wordt uitgevoerd wanneer het eindpunt van de route wordt bereikt met het toegestane HTTP-verzoek (GET, POST, PATCH, enz.). We gebruiken de `UploadController` voor alle routes en hebben deze als volgt gespecificeerd:
De laatste methode die we op elke route aanroepen, is de functie `name()`, die een enkele tekenreeks als argument accepteert en wordt gebruikt om een specifieke route min of meer te "taggen" met een gemakkelijk te onthouden naam (in onze gevallen: `upload`, `process` en `list`). Het lijkt misschien niet zo'n geweldige functie om elke route een eigen naam te geven, terwijl... URL Het heeft precies dezelfde naam, maar het komt vooral van pas als je een specifieke route hebt zoals /users/profile/dashboard/config, die makkelijker te onthouden is als profile-admin of user-config.
Een opmerking over gevels:
- Facades bieden een "statische" interface naar klassen die beschikbaar zijn in de servicecontainer van de applicatie.
- Ze bieden een beknopte, gedenkwaardige syntaxis waarmee u de functies van Laravel kunt gebruiken zonder lange klassenamen te onthouden die handmatig moeten worden geïnjecteerd of geconfigureerd.
In de bovenstaande routedefinities gebruiken we de Route-facade in plaats van handmatig een nieuw Illuminate/Routing/Router-object te instantiëren en de bijbehorende methoden op dat object aan te roepen. Het is gewoon een kortere weg die tijd bespaart.pingFacades worden veelvuldig gebruikt in het Laravel-framework; het is raadzaam om er meer over te leren. De documentatie voor Facades is te vinden op [link]. hier.
Wat is een controleur?
Een controller is de “C” in de “MVC” (Model-View-Controller) architectuur, waarop Laravel is gebaseerd. De taak van een controller kan worden samengevat in deze simpele definitie: Het ontvangt het verzoek van de klant en stuurt een antwoord terug naar de klant. Dit is de meest basale definitie en tevens de minimale vereiste voor elke controller. Wat er tussen deze twee aspecten gebeurt, wordt over het algemeen beschouwd als de "actie" van de controller (of de "implementatie van de route"). De controller fungeert als het tweede toegangspunt tot de applicatie (het eerste is het verzoek) voor de client, die de verzoekpayload (waar we later op terugkomen) naar de applicatie stuurt en een reactie verwacht (in de vorm van een succespagina, een redirect, een foutpagina of een andere HTTP-respons).
Een controller doet (in principe) hetzelfde als een routedefinitie met een anonieme functie die is ingesteld als de "actie" wanneer die route wordt aangeroepen. Het verschil is dat een controller zich goed houdt aan het principe van scheiding van verantwoordelijkheden, terwijl een route inline met de eigenlijke code wordt gedefinieerd. URL definitie, wat in feite betekent dat we de aan de route toegewezen URI koppelen aan de implementatie van de route, oftewel de code die wordt uitgevoerd wanneer die route wordt aangeroepen.
De volgende twee stukjes code bereiken bijvoorbeeld hetzelfde:
Voorbeeld #1: Routedefinitie en -implementatie binnen een enkele methodeaanroep (in het web.php routesbestand)
//inside routes/web.php
<?php
Route::get('/hello-world', function(Request $request) {
$name = $request->name;
return response()->make("<h1>Hello World! This is ".$name, 200);
});
Voorbeeld #2: De routedefinitie bevindt zich in routes/web.php, maar de implementatie ervan bevindt zich in de klasse /app/Http/Controllers/HelloWorldController.
//inside routes/web.php
<?php
Route::get('/hello-world', 'HelloWorldController@index')->name('hello-world');
------------------------------------------------------------------------------------
//inside app/Http/Controllers/HelloWorldController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HelloWorldController extends Controller
{
public function index(Request $request)
{
$name = $request->name;
return response()->make("<h1>Hello World! This is ".$name, 200);
}
}
Hoewel Laravel-voorbeeld #2 veel meer werk lijkt te vereisen (wat niet het geval is, slechts een beetje meer code), kijk eens naar de voordelen die we behalen door onze actielogica voor de gegeven "hello-world"-route in een controller te plaatsen in plaats van in de routedefinitie als een callbackfunctie:
- Onze logica is duidelijk afgescheiden in een eigen klasse (scheiding van verantwoordelijkheden).
- Onze controller is zo opgezet dat hij later kan worden uitgebreid als we extra functionaliteiten willen toevoegen. Stel dat we een "tot ziens"-functie willen toevoegen. In dat geval zouden we de controller hernoemen naar een meer algemene naam zoals "HelloController" en vervolgens twee aparte methoden definiëren. Hallo() en tot ziens(). We zouden ook twee afzonderlijke routes moeten definiëren die de route in kaart brengen /Hallo en / tot ziens URI's verwijzen naar de bijbehorende methode in de controller. Dit is wenselijker dan een routesbestand vol te stoppen met callbackfuncties voor elke route.
- Laravel heeft de ingebouwde mogelijkheid om alle routedefinities in de applicatie in de cache op te slaan, zodat het de tijd versnelt die nodig is om een bepaalde route te vinden (verhoogt de applicatieprestaties); echter Je kunt daar alleen van profiteren als al je gedefinieerde routes binnen de applicatie geconfigureerd zijn met behulp van controllerspecifieke kaarten.pings (zie voorbeeld nr. 2 hierboven).
Laten we dit commando uitvoeren; hiermee genereren we een nieuwe controller.
// ...inside the project's root directory: php artisan make:controller UploadController
In essentie genereert dit commando een placeholder voor een controller met de naam "UploadController" in de hoofdcontrollerdirectory op /app/Http/Controllers/UploadController.php. U kunt dit bestand gerust openen en bekijken. Het is heel eenvoudig, omdat het slechts een uitgeklede versie van de controller is, met het juiste namespacepad en de vereiste klassen waarvan deze overerft.
Het genereren van het verzoek
Voordat we verdergaan met deze PHP Laravel-tutorial en een paar wijzigingen aanbrengen in de gegenereerde stub van de UploadController, is het handiger om eerst de request-klasse te maken. Dit komt omdat de controllermethode die het verzoek afhandelt, het request-object in de signature moet type-hinten, zodat de binnenkomende formuliergegevens automatisch gevalideerd kunnen worden (zoals gespecificeerd in de rules()-methode; daarover later meer). Laten we nu de artisan-opdracht opnieuw gebruiken om onze request-stub te genereren:
php artisan make:request UploadFileRequest
Met dit commando wordt een bestand met de naam UploadFileRequest aangemaakt in de map app/Http/Requests/UploadFileRequest. Open het bestand en bekijk het eens. Je zult zien dat het erg eenvoudig is en slechts twee methoden bevat: authorize() en rules().
Het creëren van de validatielogica
Laten we de request stub aanpassen aan de behoeften van onze applicatie. Wijzig het bestand zodat het er als volgt uitziet:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UploadFileRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'fileName' => 'required|string',
'userFile' => 'required|file'
];
}
}
Er zijn niet heel veel veranderingen, maar let op dat de `authorize()`-methode nu `true` retourneert in plaats van `false`. Deze methode bepaalt of het verzoek al dan niet toegang krijgt tot de applicatie. Als de waarde `false` is, wordt het verzoek geblokkeerd. Dit zou een handige plek zijn om autorisatiecontroles op de gebruiker of andere logica te plaatsen die bepaalt of het verzoek naar de controller kan worden doorgestuurd. Voorlopig retourneren we hier echter `true` om alles en iedereen toegang te geven tot het verzoek.
De andere methode, rules(), is waar alle magie met betrekking tot validatie in beeld komt. Het idee is simpel: retourneer een array met een set regels in de vorm van:
'formFieldName' => 'constraints this field has separated by pipe characters (|)'
Er zijn veel verschillende validatiebeperkingen die direct uit de doos door Laravel worden ondersteund. Voor een volledige lijst hiervan, bekijk de online documentatie hierVoor onze uploadapplicatie gebruiken we twee velden die via een POST-verzoek vanuit een formulier op de front-end worden doorgegeven. De parameter `fileName` moet in de formulierbody worden opgenomen (dus verplicht) en wordt gebruikt als de bestandsnaam waaronder we het bestand in de opslag opslaan (dit gebeurt in de controller; we komen hier later op terug). We specificeren ook dat de bestandsnaam een tekenreeks moet zijn door een verticale streep (|) en het woord 'string' toe te voegen. Beperkingen worden altijd gescheiden door verticale strepen, waardoor je eventuele aanvullende criteria voor het betreffende veld op één regel kunt specificeren.
De tweede parameter, userFile, is het daadwerkelijke bestand dat de gebruiker uploadt via een formulier op een webpagina. userFile is ook verplicht. Dan moet je een bestand zijn. Let op: Als we verwachtten dat het geüploade bestand een afbeelding zou zijn, zouden we in plaats daarvan de afbeeldingsbeperking gebruiken, die de geaccepteerde bestandstypen zou beperken tot een van de gangbare afbeeldingstypen (jpeg, png, bmp, gif of svg). Omdat we de gebruiker echter elk type bestand willen laten uploaden, houden we het bij de bestandsvalidatiebeperking.
Dat is in principe alles wat er te zeggen valt over het request-object. De belangrijkste functie ervan is het vastleggen van de acceptabele criteria (beperkingen) waaraan de parameters in de formulierbody moeten voldoen om verder te kunnen gaan in de applicatie. Het is ook belangrijk om te weten dat deze twee velden (userFile en fileName) ook in de HTML-code moeten worden gespecificeerd als inputvelden (waarbij de veldnaam overeenkomt met de naam in het request-object).
Je vraagt je misschien af: dit definieert de kenmerken van wat een formulierverzoek moet bevatten, maar waar wordt er daadwerkelijk gecontroleerd of aan deze beperkingen wordt voldaan? Daar gaan we zo meteen op in.
De regelaar aanpassen
Open app/Http/Controllers/UploadController en breng de volgende wijzigingen aan:
<?php
namespace App\Http\Controllers;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Http\Request;
use App\Http\Requests\UploadFileRequest; //our new request class
use Illuminate\Support\Facades\Storage;
class UploadController extends Controller
{
/**
* This is the method that will simply list all the files uploaded by name and provide a
* link to each one so they may be downloaded
*
* @param $request : A standard form request object
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws BindingResolutionException
*/
public function list(Request $request)
{
$uploads = Storage::allFiles('uploads');
return view('list', ['files' => $uploads]);
}
/**
* @param $file
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
* @throws BindingResolutionException
*/
public function download($file)
{
return response()->download(storage_path('app/'.$file));
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws BindingResolutionException
*/
public function upload()
{
return view('upload');
}
/**
* This method will handle the file uploads. Notice that the parameter's typehint
* is the exact request class we generated in the last step. There is a reason for this!
*
* @param $request : The special form request for our upload application
* @return array|\Illuminate\Http\UploadedFile|\Illuminate\Http\UploadedFile[]|null
* @throws BindingResolutionException
*/
public function process(UploadFileRequest $request)
{
//At this point, the parameters passed into the $request (from form) are
//valid--they satisfy each of the conditions inside the rules() method
$filename = $request->fileName; //parameters have already been validated
$file = $request->file('userFile'); //so we don't need any additional isset()
$extension = $file->getClientOriginalExtension(); //grab the file extension
$saveAs = $filename . "." . $extension; //filename to save file under
$file->storeAs('uploads', $saveAs, 'local'); //save the file to local folder
return response()->json(['success' => true]); //return a success message
}
}
Het is dus een vrij eenvoudige manier om de geüploade bestanden op de schijf op te slaan. Hier volgt een uitleg van de bovenstaande `process()`-methode:
- Voeg een typehint toe aan de requestklasse in de controllermethode die de hoofdfunctionaliteit uitvoert, zodat we de binnenkomende data automatisch kunnen valideren.
- Haal het bestand uit het (nu gevalideerde) request-object in de controller-methode.
- Haal de bestandsnaam uit het verzoek.
- Genereer de uiteindelijke bestandsnaam waaronder het bestand zal worden opgeslagen. De methode getClientOriginalExtension() pakt eenvoudigweg de oorspronkelijke extensie van het geüploade bestand.
- Sla het bestand op in het lokale bestandssysteem met behulp van de storeAs()-methode, waarbij u het benoemde pad in de map /storage als eerste argument doorgeeft en de bestandsnaam waaronder u het wilt opslaan als tweede.
- Retourneer een JSON-antwoord dat aangeeft dat het verzoek succesvol was.
Het bladsjabloon
Het laatste belangrijke onderdeel van deze puzzel is de blade-template, die alle HTML, CSS en JavaScript voor onze eenvoudige applicatie. Hier is de code; we zullen deze later toelichten.
<body>
<h1>Upload a file</h1>
<form id="uploadForm" name="uploadForm" action="{{route('process')}}" enctype="multipart/form-data">
@csrf
<label for="fileName">File Name:</label>
<input type="text" name="fileName" id="fileName" required /><br />
<label for="userFile">Select a File</label>
<input type="file" name="userFile" id="userFile" required />
<button type="submit" name="submit">Submit</button>
</form>
<h2 id="success" style="color:green;display:none">Successfully uploaded file</h2>
<h2 id="error" style="color:red;display:none">Error Submitting File</h2>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$('#uploadForm').on('submit', function(e) {
e.preventDefault();
var form = $(this);
var url = form.attr('action');
$.ajax({
url: url,
type: "POST",
data: new FormData(this),
processData: false,
contentType: false,
dataType: "JSON",
success: function(data) {
$("#fileName").val("");
$("#userFile").val("");
}
}).done(function() {
$('#success').css('display', 'block');
window.setTimeout(()=>($("#success").css('display', 'none')), 5000);
}).fail(function() {
$('#error').css('display', 'block');
window.setTimeout(()=>($("#error").css('display', 'none')), 5000);
});
});
</script>
</body>
</html>
Dit is wat onze /uploaden pagina ziet er als volgt uit:
Dit is een heel typisch voorbeeld van een Blade-bestand met een HTML-formulier. JavaScript/jQuery voor het toevoegen van asynchrone functionaliteit (zodat de pagina niet opnieuw wordt geladen). Er is een basis Een tag zonder method-attribuut (wat we zo meteen zullen uitleggen) en met een merkwaardig action-attribuut met de waarde {{route('process')}}. In Blade staat dit bekend als een Richtlijn. Een directive is gewoon een chique naam voor een functie; het zijn functies die specifiek zijn voor Blade-templates en die verschillende bewerkingen uitvoeren die gebruikelijk zijn bij het bouwen van webpagina's en webapplicaties. Voor een beter begrip van alle nuttige mogelijkheden van Blade, raadpleeg de documentatie. hierIn het bovenstaande voorbeeld gebruiken we de route-richtlijn om een route te genereren. URL voor onze formulierinzending.
Onthoud dat we onze routes eerder in de applicatie in het bestand web.php hebben gedefinieerd, waarbij we voor elke route een gemakkelijk te onthouden naam hebben opgegeven. De {{route()}}-richtlijn accepteert de naam van een route, zoekt deze op in de intern opgeslagen lijst met routes en genereert een volledige route-ID. URL gebaseerd op de definitie van die route in het web.php-bestand. In dit eerste geval specificeren we dat we willen dat het formulier de ingediende gegevens naar /process stuurt. URL van onze applicatie, die wordt gedefinieerd als een POST route.
Het volgende dat je wellicht is opgevallen, is de `@csrf`-tag direct onder de openingstag van het formulier. In Blade genereert deze tag een `_token`-parameter voor het formulier, die binnen de applicatie wordt gecontroleerd voordat de formuliergegevens mogen worden verwerkt. Dit zorgt ervoor dat de gegevens in het formulier van een geldige oorsprong zijn en voorkomt cross-site request forgery-aanvallen. Zie voor meer informatie hierover de documentatie. docs.
Hierna definiëren we ons formulier zoals gebruikelijk; let er echter op dat de namen van onze formulierparameters, userFile en fileName, hetzelfde zijn. exact dezelfde zoals gedefinieerd in ons request-object. Als we vergeten een invoer voor een bepaalde parameter die in het request-object is gedefinieerd op te nemen (of deze verkeerd spellen), zal het verzoek mislukken en een foutmelding retourneren. Hierdoor zal het oorspronkelijke formulierverzoek de controllermethode op UploadController@process nooit bereiken.
Probeer het gerust uit en upload een paar bestanden naar de applicatie via dit formulier. Ga daarna naar de /lijst pagina om de inhoud van de uploadmap te zien, met de bestanden die u hebt geüpload in een tabel:
The Bigger Picture
Laten we even een stap terug doen en bekijken wat we in deze Laravel-tutorial hebben gedaan.
Dit diagram toont de applicatie zoals die er momenteel uitziet (details op hoog niveau weggelaten):
Houd er rekening mee dat het request-object dat we aan het begin van deze Laravel-tutorial hebben gemaakt, dezelfde parameters in de rules-methode moet hebben als het formulier in de Blade-template (zo niet, lees dan het gedeelte 'De validatielogica maken' opnieuw). De gebruiker vult het formulier in op een webpagina die wordt weergegeven via de Blade-template-engine en verzendt het formulier. De jQuery-code onderaan de template voorkomt de standaardverzending (die automatisch zou doorverwijzen naar een andere pagina), maakt een Ajax-verzoek aan, laadt het verzoek met de formuliergegevens en het geüploade bestand en stuurt het geheel naar de eerste laag van onze applicatie: de request.
Het request-object wordt gevuld door de parameters in de `rules()`-methode te koppelen aan de parameters van het ingediende formulier. Vervolgens worden de gegevens gevalideerd volgens elke opgegeven regel. Als aan alle regels is voldaan, wordt het verzoek doorgegeven aan de controllermethode die overeenkomt met de waarden die zijn gedefinieerd in het routebestand `web.php`. In dit geval is dat de `process()`-methode van de `UploadController`. Zodra we de controller bereiken, weten we al dat het verzoek de validatie heeft doorstaan, dus hoeven we niet opnieuw te controleren of de opgegeven bestandsnaam daadwerkelijk een string is of dat de parameter `userFile` daadwerkelijk een bestandstype bevat. We kunnen gewoon verdergaan.
De controllermethode haalt vervolgens de gevalideerde parameters uit het request-object, genereert een volledige bestandsnaam door de meegeleverde parameter `fileName` te concateneren met de oorspronkelijke extensie van het bestand van de gebruiker, slaat het bestand op in een map in onze applicatie en retourneert vervolgens een eenvoudige JSON-gecodeerde respons die bevestigt dat het verzoek succesvol was. De respons wordt ontvangen door de jQuery-logica, die nog een aantal UI-gerelateerde taken uitvoert, zoals het weergeven van het succes- (of fout)bericht gedurende 5 seconden en het vervolgens verbergen ervan, en het wissen van de vorige formulierinvoer. Zo weet de gebruiker zeker dat het verzoek succesvol was en kan hij of zij indien gewenst een ander bestand uploaden.
Let ook op waar in het bovenstaande diagram de grens tussen de client en de server is getrokken. Dit concept is absoluut cruciaal om te begrijpen en zal u helpen bij het oplossen van problemen die u in de toekomst kunt tegenkomen, bijvoorbeeld bij het verwerken van meerdere asynchrone verzoeken die tegelijkertijd kunnen plaatsvinden. De scheiding bevindt zich precies op de grens van het request-object. Het request-object zelf kan worden gezien als de "gateway" naar de rest van de applicatie. Het voert de initiële validatie en registratie uit van de formulierwaarden die vanuit de webbrowser worden doorgegeven. Als deze geldig worden bevonden, gaat het verder naar de controller. Alles wat daaraan voorafgaat, gebeurt aan de front-end (de "client" betekent letterlijk "op de computer van de gebruiker"). Het antwoord wordt vanuit de app teruggestuurd naar de client, waar onze jQuery-code geduldig wacht op de aankomst ervan en een paar eenvoudige UI-taken uitvoert zodra het is ontvangen.
We hebben ook veel belangrijke, veelgestelde vragen beantwoord. Laravel- en PHP-gerelateerde interviewvragen voor zowel eerstejaars als ervaren kandidaten om de juiste baan te vinden.







