Les 2 · Module 1 · Laravel-basis
Routes en controllers
Verplaats de logica van de kassa uit routes/web.php naar controllers: routeparameters, benoemde routes, resource-controllers en route-groepen.
🎯 Na deze les kun je
- een controller maken met artisan en routes eraan koppelen
- benoemde routes gebruiken met route()
- een resource-controller voor CRUD-routes aanmaken
- routes groeperen met prefix en name
In les 1 stond je code direct in routes/web.php. Met drie routes gaat dat, met dertig niet: het routebestand wordt
een rommelbak. Laravel scheidt daarom welke URL (de route) van wat er gebeurt (de controller). Een
controller is een gewone PHP-klasse met een methode per actie.
Je eerste controller
php artisan make:controller KassaController
// app/Http/Controllers/KassaController.php
namespace App\Http\Controllers;
class KassaController extends Controller
{
public function totaal(int $bedrag)
{
$btw = round($bedrag * 0.21, 2);
return view('kassa.totaal', compact('bedrag', 'btw'));
}
}
// routes/web.php
use App\Http\Controllers\KassaController;
Route::get('/totaal/{bedrag}', [KassaController::class, 'totaal'])
->whereNumber('bedrag')
->name('kassa.totaal');
view('kassa.totaal') zoekt resources/views/kassa/totaal.blade.php: de punt is een map. compact('bedrag', 'btw')
maakt ['bedrag' => $bedrag, 'btw' => $btw].
Benoemde routes
Met ->name('kassa.totaal') geef je de route een naam. Links maak je dan met route():
<a href="{{ route('kassa.totaal', ['bedrag' => 50]) }}">Totaal van 50</a>
Verander je later de URL in /kassa/totaal/{bedrag}, dan blijven alle links werken.
Voorspel eerst: wat geeft route('kassa.totaal', ['bedrag' => 50, 'fooi' => 10])?
Uitkomst
http://127.0.0.1:8000/totaal/50?fooi=10. Parameters die in de route staan gaan in het pad, de rest wordt een
query-string. Vergeet je bedrag, dan krijg je een UrlGenerationException: Missing required parameter.
Optionele parameters en de request
Route::get('/fooi/{bedrag}/{procent?}', [KassaController::class, 'fooi'])->whereNumber(['bedrag', 'procent']);
public function fooi(Request $request, int $bedrag, int $procent = 10)
{
$afronden = $request->boolean('afronden'); // ?afronden=1
$fooi = $bedrag * $procent / 100;
return view('kassa.fooi', ['fooi' => $afronden ? ceil($fooi) : $fooi]);
}
Laravel geeft je methode automatisch een Request-object als je er een type voor zet (use Illuminate\Http\Request;).
Dat heet dependency injection; in les 4 zie je hoe dat werkt.
Resource-controllers
Voor producten wil je de standaard CRUD-acties. Eén commando maakt een controller met zeven methodes:
php artisan make:controller ProductController --resource
Route::resource('producten', ProductController::class)->parameters(['producten' => 'product']);
| Methode | URL | Actie | Naam |
|---|---|---|---|
| GET | /producten |
index | producten.index |
| GET | /producten/create |
create | producten.create |
| POST | /producten |
store | producten.store |
| GET | /producten/{product} |
show | producten.show |
| GET | /producten/{product}/edit |
edit | producten.edit |
| PUT/PATCH | /producten/{product} |
update | producten.update |
| DELETE | /producten/{product} |
destroy | producten.destroy |
->parameters(...) is nodig omdat Laravel van "producten" geen Engels enkelvoud kan maken.
Route-groepen
Route::prefix('kassa')->name('kassa.')->controller(KassaController::class)->group(function () {
Route::get('/', 'index')->name('index'); // /kassa → kassa.index
Route::get('/bon', 'bon')->name('bon'); // /kassa/bon → kassa.bon
Route::post('/bon/regels', 'toevoegen')->name('toevoegen');
});
Typische fouten
Target class [KassaController] does not exist: deuse-regel bovenaanweb.phpontbreekt.Route [kassa.totaal] not defined: tikfout in de naam, of de route staat in een groep met eenname-prefix./producten/createtoont een product "create": je hebt een eigen/producten/{product}-route boven de resource gezet. Volgorde telt.
Oefenen
- Verplaats
/totaal,/overen/kortinguit les 1 naarKassaControlleren geef ze namen. - Maak een menu in een view met
route()-links naar alle drie. - Maak
ProductControllerals resource en laatindexvoorlopig een vaste array met drie producten tonen. - Zet de kassa-routes in een groep met prefix
kassaen naam-prefixkassa..
Modelantwoord oefening 1
Route::controller(KassaController::class)->group(function () {
Route::get('/totaal/{bedrag}', 'totaal')->whereNumber('bedrag')->name('kassa.totaal');
Route::get('/korting/{bedrag}/{procent}', 'korting')->whereNumber(['bedrag', 'procent'])->name('kassa.korting');
});
Route::view('/over', 'over')->name('over');
Modelantwoord oefening 2
<nav>
<a href="{{ route('over') }}">Over</a>
<a href="{{ route('kassa.totaal', 100) }}">Totaal</a>
<a href="{{ route('kassa.korting', [80, 25]) }}">Korting</a>
</nav>
Bij één parameter mag je hem los meegeven; bij meer een array in de volgorde van de route.
Modelantwoord oefening 3
public function index()
{
$producten = [['naam' => 'koffie', 'prijs' => 2.80], ['naam' => 'thee', 'prijs' => 2.50], ['naam' => 'appeltaart', 'prijs' => 4.25]];
return view('producten.index', compact('producten'));
}
In les 8 komt deze lijst uit de database.
Modelantwoord oefening 4
php artisan route:list --path=kassa toont alleen de routes onder /kassa, met namen als kassa.bon.
Lokaal oefenen
Geen live lab. Gebruik php artisan route:list en curl -i om elke route te controleren.
Samenvatting
- Routes zeggen welke URL; controllers zeggen wat er gebeurt.
- Geef routes een naam en link met
route(). Route::resourcemaakt in één regel de zeven CRUD-routes; groepen houdenweb.phpoverzichtelijk.- Volgende les: Blade-templates en componenten.