Door
Tom Swinkels
op 22-02-2013 23:03
gewijzigd op 07-09-2013 17:20
6.847 views
Beste Developers,
Ik zie vaak allemaal ingewikkelde routers tegen komen op internet.
Na even te zoeken kwam ik een vrij simpele router tegen hier op PHPHulp.
Wat is de reden van een uitgebreide moeilijke router? Na mijn mening is dit toch prima?
Enige probleem dat ik nu nog heb, is dat wanneer ik nu naar /artikel/bewerk/234/ dat hij de route /artikel/ pakt, hoe kan ik dit op de beste manier oplossen? Alles een prioriteit meegeven, sorteren op langste route? Wat is de beste manier hiervoor? Of gewoon een kwestie van de routes aanmaken in de goede volgorde?
<?php
class Router
{
private $_routes;
public function __construct()
{
$this->_routes = array();
}
public function setRoute( Route $route )
{
$this->_routes[] = $route;
}
public function match( $query )
{
$routes = $this->_routes;
if( $routes )
{
foreach( $routes as $route )
{
$match = $route->match( $query );
if( $match )
{
return $match;
}
}
}
return false;
}
}
class Route
{
private $_regex;
private $_controller;
public function __construct( $pattern, $controller )
{
$this->_regex = preg_replace( '#:([a-z])+#','(?P<$1>[^/]+)', $pattern );
$this->_controller = $controller;
}
public function match( $query )
{
if( !preg_match( '#'.$this->_regex.'#', $query, $matches ) )
{
return false;
}
$controller = new Controller();
$controller->setName( $this->_controller );
return $controller;
}
}
class Controller
{
private $_name;
public function setName( $name )
{
$this->_name = $name;
}
public function getName()
{
return $this->_name;
}
}
$router = new Router();
$router->setRoute( new Route( '/artikel/', 'article.view.module') );
$router->setRoute( new Route( '/artikel/bewerk/:id', 'article.edit.module') );
$router->setRoute( new Route( '/artikel/verwijder/:id', 'article.delete.module') );
$controller = $router->match( $request->server( 'REDIRECT_URL' ) );
?>
Dat hangt ervan af wat je met een 404 wilt doen en kunt doen. Domweg een "niet gevonden" melden is de kortste route, maar ook de weg van de minste weerstand.
Persoonlijk denk ik dat je hiermee niet kunt wegkomen bij een slimme website. Fouten melden kan iedereen, maar fouten voor gebruikers oplossen is een kunst.
Wat doe je bijvoorbeeld bij één misplaatst karakter in een URL? Gooi je dan meteen de "404 Not Found"-handdoek in de ring? Of laat je direct de webpagina zien die het meest overeenkomt met de request van de client? Of meldt je de fout en toon je de meest geschikte routes?
Kies maar... het juiste antwoord lijkt me duidelijk.
Waarom? Navigatie loopt via links, en als een of andere idio(o)t(e) in de url wil gaan lopen rommelen is het niet meer normaal dat hij/zij een page not found handoek aangereikt krijgt.
Waarom? Navigatie loopt via links, en als een of andere idio(o)t(e) in de url wil gaan lopen rommelen is het niet meer normaal dat hij/zij een page not found handoek aangereikt krijgt.
Bijvoorbeeld voor backlinks die worden gemaakt door onhandige kopiëren-en-plakkers of door hun kromme tools in krom geschreven PHP...
Als daar een é of een ë in zit, loopt een router vaak vast. Je zou echter ook kunnen kiezen voor een router die snapt dat een é of een ë eigenlijk een e is.
Het gaat om de 2 vragen, over de registry en over de error pagina.
Het gaat er niet over uit wat voor error pagina.
Wie is er verantwoordelijk voor, is dat de router of de controller?
Nogmaals, de router gaat over de routes, dus ik zou zeggen dat de router een default route krijgt en als hij een route niet gevonden krijgt stuurt hij alles door naar de default route?
Je hebt een route nodig om bij een controller te komen. Dus je gooit een Exception in de router wanneer er geen gevonden is. Dan kan je die Exception op twee manieren afhandelen: in een try-catch block, of in een exception handler. Ik heb een voorbeeld gegeven van het laatste.
Wie zegt dat ik een 404 pagina wil zien wanneer de route niet gevonden is?
Misschien wil ik standaard als de pagina niet bestaat altijd de homepagina zien?
Ik zal nog eens wat dingen over Dependency Injection lezen. Start daar anders wel een nieuw topic over, kunnen we hier nog even het router verhaal afronden.
...
404 is de error code voor "File Not Found". Een 404 pagina is dus een pagina die je laat zien wanneer er een bestand/route niet gevonden is. Als jij je home page als 404 pagina wilt gebruiken, prima. Daar ging het me niet om.
Waar ik het niet mee eens ben is het idee van een default route. Ik wil dat je een exception gooit, of dit nou een RouteNotFoundException, HTTP404Excption, FileNotFoundException of een ander genaamde exception is maakt me niet uit.
"De router is toch verantwoordelijk voor alle routes, het lijkt mij dus toch logisch om daarvoor een default route te maken?" De router is verantwoordelijk om zo mogelijk een route voor de opgegeven URI te vinden. Die route wordt daarna gebruikt om de juiste method van een controller class uit te laten voeren.
Als er geen route gevonden is het een 'exceptional situation' naar mijn idee. De router gooit dus een exception die hoger op in je applicatie gebruikt wordt om te bepalen wat er nu gebeurd moet worden. In dit geval de homepage voorschotelen. En er misschien nog een melding aan toe te voegen zodat de gebruiken weet dat de opgegeven URI ongeldig is.