route class
Pagina: « vorige 1 2 3 volgende »
Oke... duurt altijd zo lang :)
Ondertussen heb ik alvast wat wijzigingen aangebracht in mijn router.
Route.class.php
Router.class.php
Dit stukje zou dan uiteindelijk in de FrontController moeten komen??
Route.class.php
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
/**
* @author Tom Swinkels
* @version v1.0 last edit on 08-09-2013
*/
class Route
{
private $_pattern;
private $_data;
public function __construct( $pattern, $data )
{
$this->_pattern = $pattern;
$this->_data = $data;
}
public function match( $query )
{
// ADD EXPESSION FOR MATCHING.
$route = '#^' . $query . '$#';
// CHECK FOR NUMERIC ROUTE
$route = preg_replace( '/\<\#(.*?)\>/', '(?P<\1>[0-9]+)', $route );
// CHECK FOR ALPHA NUMERIC ROUTE
$route = preg_replace( '/\<\:(.*?)\>/', '(?P<\1>[A-Za-z0-9\-\_]+)', $route );
if( preg_match( $route, $query, $matches ) )
{
return $this->_data;
}
return false;
}
}
?>
/**
* @author Tom Swinkels
* @version v1.0 last edit on 08-09-2013
*/
class Route
{
private $_pattern;
private $_data;
public function __construct( $pattern, $data )
{
$this->_pattern = $pattern;
$this->_data = $data;
}
public function match( $query )
{
// ADD EXPESSION FOR MATCHING.
$route = '#^' . $query . '$#';
// CHECK FOR NUMERIC ROUTE
$route = preg_replace( '/\<\#(.*?)\>/', '(?P<\1>[0-9]+)', $route );
// CHECK FOR ALPHA NUMERIC ROUTE
$route = preg_replace( '/\<\:(.*?)\>/', '(?P<\1>[A-Za-z0-9\-\_]+)', $route );
if( preg_match( $route, $query, $matches ) )
{
return $this->_data;
}
return false;
}
}
?>
Router.class.php
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
/**
* @author Tom Swinkels
* @version v1.0 last edit on 08-09-2013
*/
class Router
{
private $_routes;
public function __construct()
{
$this->_routes = array();
}
public function setRoute( Route $route )
{
$this->_routes[] = $route;
}
public function getRoute( $query )
{
$routes = $this->_routes;
if( $routes )
{
foreach( $routes as $route )
{
$match = $route->match( $query );
if( $match )
{
$controllerName = $match['controller'] . 'Controller';
$controller = new $controllerName();
$controller->$match['action']();
return $controller;
}
}
}
return false;
}
}
?>
/**
* @author Tom Swinkels
* @version v1.0 last edit on 08-09-2013
*/
class Router
{
private $_routes;
public function __construct()
{
$this->_routes = array();
}
public function setRoute( Route $route )
{
$this->_routes[] = $route;
}
public function getRoute( $query )
{
$routes = $this->_routes;
if( $routes )
{
foreach( $routes as $route )
{
$match = $route->match( $query );
if( $match )
{
$controllerName = $match['controller'] . 'Controller';
$controller = new $controllerName();
$controller->$match['action']();
return $controller;
}
}
}
return false;
}
}
?>
Dit stukje zou dan uiteindelijk in de FrontController moeten komen??
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$router = new Router();
$router->setRoute( new Route( '/artikel/bewerk/<#id>/', array( 'controller' => 'Article', 'module' => 'edit', 'action' => 'index' ) ) );
$controller = $router->getRoute( $request->server( 'REDIRECT_URL' ) );
?>
$router = new Router();
$router->setRoute( new Route( '/artikel/bewerk/<#id>/', array( 'controller' => 'Article', 'module' => 'edit', 'action' => 'index' ) ) );
$controller = $router->getRoute( $request->server( 'REDIRECT_URL' ) );
?>
Gewijzigd op 08/09/2013 22:30:41 door Tom Swinkels
De routes toevoegen wordt natuurlijk in een configuratie bestand gezet. Andere punten:
- de router heeft niks van doen met het koppelen van een route aan een controller, dit moet de front controller of een controller resolver doen.
- regel 22 van de router is nodeloos geheugen verspilling
- gebruik liever count om te kijken of er routes zijn
- een method addRoute beschrijft de functie beter
- gebruik in het geval van ids natuurlijk wel <#id>
- geen routes om in te zoeken zou ik opvatten als een fout
- de router heeft niks van doen met het koppelen van een route aan een controller, dit moet de front controller of een controller resolver doen.
- regel 22 van de router is nodeloos geheugen verspilling
- gebruik liever count om te kijken of er routes zijn
- een method addRoute beschrijft de functie beter
- gebruik in het geval van ids natuurlijk wel <#id>
- geen routes om in te zoeken zou ik opvatten als een fout
Ik heb de Route.class.php nog wat aangepast.
Bedankt voor je antwoord, hier kan ik wat mee!
Antwoorden op jou vragen:
- Ik return enkel de data, en in de FrontController roep ik de nieuwe controllers aan bedoel je?
- Regel 22?
- Waarom zou je dat met count kijken?
- Dit had ik nog niet aangepast.
- Wat bedoel je met geen routes om in te zoeken?
Hoe zou jij een default route afhandelen / toevoegen?
Verder geeft het bovenstaande stuk matches op alles.
Bedankt voor je antwoord, hier kan ik wat mee!
Antwoorden op jou vragen:
- Ik return enkel de data, en in de FrontController roep ik de nieuwe controllers aan bedoel je?
- Regel 22?
- Waarom zou je dat met count kijken?
- Dit had ik nog niet aangepast.
- Wat bedoel je met geen routes om in te zoeken?
Hoe zou jij een default route afhandelen / toevoegen?
Verder geeft het bovenstaande stuk matches op alles.
- Nee, je retourneert gewoon de hele route en laat de front controller lekker uitzoeken wat hij daarna met die route wil doen, dat gaat de router niks aan.
- Ja, regel 22:
- Omdat je een array hebt en geen boolean value. Gewoon een kwestie van netjes scripten. Zoals ik altijd zeg "PHP is awesome because it's noobproof, a PHP developer is awesome if he doesn't use those noobproof-features".
- Nou, stel $this->_routes is leeg, dan zou ik een exceptiontje gooien
En default routes, wat bedoel je daarmee?
- Ja, regel 22:
- Omdat je een array hebt en geen boolean value. Gewoon een kwestie van netjes scripten. Zoals ik altijd zeg "PHP is awesome because it's noobproof, a PHP developer is awesome if he doesn't use those noobproof-features".
- Nou, stel $this->_routes is leeg, dan zou ik een exceptiontje gooien
En default routes, wat bedoel je daarmee?
- Ok, maar wie roept de router aan? Aangezien de routes uit de config komen?
- Welke array bedoel je? Het is toch logies om alle routes in een array te gooien?
Ik bedoel wanneer er geen route is opgegeven, bijvoorbeeld www.site.nl hoe bepaal ik welke route er dan standaard wordt uitgevoerd?
- Welke array bedoel je? Het is toch logies om alle routes in een array te gooien?
Ik bedoel wanneer er geen route is opgegeven, bijvoorbeeld www.site.nl hoe bepaal ik welke route er dan standaard wordt uitgevoerd?
- De frontcontroller roept de router aan. Routes uit config kun je erg simpel doen met:
- Ja, maar deze array kan ook leeg zijn. Daar heb je nu een ifje voor gebruikt, zodra die leeg is zou ik dus een error gooien.
De route site.nl/ is de '/' route.
Code (frontcontroller.php) (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
class FrontController
{
public function terminate(...)
{
// ...
$router = $this->getRouter();
$route = $router->match(...);
// ... do something nice with the matched route
}
protected function getRouter()
{
$router = new Router();
require_once 'path/to/config/routes.php'; // laad routes
return $router;
}
}
?>
class FrontController
{
public function terminate(...)
{
// ...
$router = $this->getRouter();
$route = $router->match(...);
// ... do something nice with the matched route
}
protected function getRouter()
{
$router = new Router();
require_once 'path/to/config/routes.php'; // laad routes
return $router;
}
}
?>
- Ja, maar deze array kan ook leeg zijn. Daar heb je nu een ifje voor gebruikt, zodra die leeg is zou ik dus een error gooien.
De route site.nl/ is de '/' route.
Ik ga nu slapen na een indrukwekkende reportage bij SBS6 te hebben gezien.
Morgen probeer ik het een en ander uit te werken.
Een quote uit je eerste bericht in dit topic "- Je mist default values, ik kan niet zeggen dat /:slug standaard de waarde 'home' krijgt.".
Toevoeging op 09/09/2013 10:10:37:
Ik heb ondertussen wat wijzigen doorgevoerd.
FrontController
Route
Router
Morgen probeer ik het een en ander uit te werken.
Een quote uit je eerste bericht in dit topic "- Je mist default values, ik kan niet zeggen dat /:slug standaard de waarde 'home' krijgt.".
Toevoeging op 09/09/2013 10:10:37:
Ik heb ondertussen wat wijzigen doorgevoerd.
FrontController
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
/**
* @author Tom Swinkels
* @version v1.0 last edit on 09-09-2013
*/
class FrontController
{
public function __construct( $requestUri )
{
$router = $this->getRouter();
$route = $router->getRoute( $requestUri );
if( $route )
{
$data = $route->getData();
$controllerName = $data['controller'] . 'Controller';
$controller = new $controllerName();
$controller->$data['action']();
return $controller;
}
}
protected function getRouter()
{
$router = new Router();
require_once('../include/routes.php'); // laad routes
return $router;
}
}
?>
/**
* @author Tom Swinkels
* @version v1.0 last edit on 09-09-2013
*/
class FrontController
{
public function __construct( $requestUri )
{
$router = $this->getRouter();
$route = $router->getRoute( $requestUri );
if( $route )
{
$data = $route->getData();
$controllerName = $data['controller'] . 'Controller';
$controller = new $controllerName();
$controller->$data['action']();
return $controller;
}
}
protected function getRouter()
{
$router = new Router();
require_once('../include/routes.php'); // laad routes
return $router;
}
}
?>
Route
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
/**
* @author Tom Swinkels
* @version v1.0 last edit on 08-09-2013
*/
class Route
{
private $_pattern;
private $_data;
public function __construct( $pattern, $data )
{
$this->_pattern = $pattern;
$this->_data = $data;
}
public function getData()
{
return $this->_data;
}
public function match( $query )
{
// ADD EXPESSION FOR MATCHING.
$route = '#^' . $query . '$#';
// CHECK FOR NUMERIC ROUTE
$route = preg_replace( '/\<\#(.*?)\>/', '(?P<\1>[0-9]+)', $route );
// CHECK FOR ALPHA NUMERIC ROUTE
$route = preg_replace( '/\<\:(.*?)\>/', '(?P<\1>[A-Za-z0-9\-\_]+)', $route );
if( preg_match( $route, $query, $matches ) )
{
return $route;
}
return false;
}
}
?>
/**
* @author Tom Swinkels
* @version v1.0 last edit on 08-09-2013
*/
class Route
{
private $_pattern;
private $_data;
public function __construct( $pattern, $data )
{
$this->_pattern = $pattern;
$this->_data = $data;
}
public function getData()
{
return $this->_data;
}
public function match( $query )
{
// ADD EXPESSION FOR MATCHING.
$route = '#^' . $query . '$#';
// CHECK FOR NUMERIC ROUTE
$route = preg_replace( '/\<\#(.*?)\>/', '(?P<\1>[0-9]+)', $route );
// CHECK FOR ALPHA NUMERIC ROUTE
$route = preg_replace( '/\<\:(.*?)\>/', '(?P<\1>[A-Za-z0-9\-\_]+)', $route );
if( preg_match( $route, $query, $matches ) )
{
return $route;
}
return false;
}
}
?>
Router
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
/**
* @author Tom Swinkels
* @version v1.0 last edit on 08-09-2013
*/
class Router
{
private $_routes;
public function __construct()
{
$this->_routes = array();
}
public function setRoute( Route $route )
{
$this->_routes[] = $route;
}
public function getRoute( $query )
{
$routes = $this->_routes;
if( $routes )
{
foreach( $routes as $route )
{
$match = $route->match( $query );
if( $match )
{
return $route;
}
}
}
return false;
}
}
?>
/**
* @author Tom Swinkels
* @version v1.0 last edit on 08-09-2013
*/
class Router
{
private $_routes;
public function __construct()
{
$this->_routes = array();
}
public function setRoute( Route $route )
{
$this->_routes[] = $route;
}
public function getRoute( $query )
{
$routes = $this->_routes;
if( $routes )
{
foreach( $routes as $route )
{
$match = $route->match( $query );
if( $match )
{
return $route;
}
}
}
return false;
}
}
?>
Gewijzigd op 09/09/2013 10:11:28 door Tom Swinkels
Returnen in een constructor doet niets. Die instantie van de juiste controller zul je moeten opslaan in de FrontController class.
Zelf gebruik ik een aparte compiler voor het maken van de reguliere expressie en een matcher die de goede route zoekt bij de url
Naar mijn mening is zo'n route class die je als voorbeeld stelt genoeg voor kleine applicaties. Echter als je zoals Symfony ook vette dingen wilt doen als url's genereren per route bijvoorbeeld, dan moet je wat extra code toevoegen
Naar mijn mening is zo'n route class die je als voorbeeld stelt genoeg voor kleine applicaties. Echter als je zoals Symfony ook vette dingen wilt doen als url's genereren per route bijvoorbeeld, dan moet je wat extra code toevoegen
@Dos: Wat bedoel je precies?
@NOLot: Ik wacht even op wat een reactie van Wouter.
@Wouter: Wat ik eigenlijk bedoel is wanneer er geen match gevonden is, wil ik dat hij bijvoorbeeld een 404 pagina krijgt te zien. Dit zou dan een default route zijn?
@NOLot: Ik wacht even op wat een reactie van Wouter.
@Wouter: Wat ik eigenlijk bedoel is wanneer er geen match gevonden is, wil ik dat hij bijvoorbeeld een 404 pagina krijgt te zien. Dit zou dan een default route zijn?
Een constructor heeft als taak een object aan te maken. Daar kan je ook de $this eigenschappen een initiële waarde geven.
Een constructor heeft niet als taak dingen te returnen.
Zorg dus dat je nooooooit in een constructor iets returnt.
Het gaat om lijn 21 van FrontController
------
Edit:
Het hele concept van FrontController moet dus anders.
Een constructor heeft niet als taak dingen te returnen.
Zorg dus dat je nooooooit in een constructor iets returnt.
Het gaat om lijn 21 van FrontController
------
Edit:
Het hele concept van FrontController moet dus anders.
Gewijzigd op 09/09/2013 14:03:00 door Kris Peeters
@Tom, en dat is dus niet een default route. Zodra de router geen match vindt retourneert hij false of gooit hij een exception (ik heb voorkeur voor dat laatste). Wanneer dit zo is roept de front controller de 404 controller aan.
Bedoel je dan zo iets?
Wouter wat vindt jij er van om alles nog een op te splitsen naar een routerCompiler en routerMatcher?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
/**
* @author Tom Swinkels
* @version v1.0 last edit on 09-09-2013
*/
class FrontController
{
public function execute( $requestUri )
{
$router = $this->getRouter();
$route = $router->getRoute( $requestUri );
if( $route )
{
$data = $route->getData();
$controllerName = $data['controller'] . 'Controller';
$controller = new $controllerName();
$controller->$data['action']();
return true;
}
else
{
//404 CONTROLLER??
}
}
protected function getRouter()
{
$router = new Router();
require_once( dirname(__FILE__) . '/../include/routes.inc.php' ); // laad routes
return $router;
}
}
?>
/**
* @author Tom Swinkels
* @version v1.0 last edit on 09-09-2013
*/
class FrontController
{
public function execute( $requestUri )
{
$router = $this->getRouter();
$route = $router->getRoute( $requestUri );
if( $route )
{
$data = $route->getData();
$controllerName = $data['controller'] . 'Controller';
$controller = new $controllerName();
$controller->$data['action']();
return true;
}
else
{
//404 CONTROLLER??
}
}
protected function getRouter()
{
$router = new Router();
require_once( dirname(__FILE__) . '/../include/routes.inc.php' ); // laad routes
return $router;
}
}
?>
Wouter wat vindt jij er van om alles nog een op te splitsen naar een routerCompiler en routerMatcher?
oops, iets te vlug gereageerd
Gewijzigd op 09/09/2013 16:56:17 door Kris Peeters
Ja, dat bedoel ik. Behalve dat de FrontController gewoon het hele request moet krijgen en niet alleen de URI. Want hoe kun je van buiten nou weten dat hij de URI nodig heeft? Je weet alleen dat hij informatie uit de Request nodig heeft.
Het gebruiken van een Compiler lijkt me niet nodig, het gebruiken van een UrlMatcher oid lijkt me wel een tof plan.
Het gebruiken van een Compiler lijkt me niet nodig, het gebruiken van een UrlMatcher oid lijkt me wel een tof plan.
Dat gedeelte heb ik aangepast.
UrlMatcher kan altijd nog.
Er gaan op dit moment nog iets mis met de match hij matcht namelijk alles.
Toevoeging op 09/09/2013 23:45:31:
Probleem is opgelost.
Ik match de query met de query, maar ik moet natuurlijk de query matchen met de route.
Toevoeging op 10/09/2013 00:11:10:
Wat ik nu nog mis is een Registry zoals hier http://phpro.org/tutorials/Model-View-Controller-MVC.html wordt beschreven.
Zouden jullie dit op de zelfde manier doen? Of is het een slecht voorbeeld?
UrlMatcher kan altijd nog.
Er gaan op dit moment nog iets mis met de match hij matcht namelijk alles.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?
public function match( $query )
{
// ADD EXPESSION FOR MATCHING.
$route = '#^' . $query . '$#';
// CHECK FOR NUMERIC ROUTE
$route = preg_replace( '/\<\#(.*?)\>/', '(?P<\1>[0-9]+)', $route );
// CHECK FOR ALPHA NUMERIC ROUTE
$route = preg_replace( '/\<\:(.*?)\>/', '(?P<\1>[A-Za-z0-9\-\_]+)', $route );
if( preg_match( $route, $query, $matches ) )
{
return $route;
}
return false;
}
?>
public function match( $query )
{
// ADD EXPESSION FOR MATCHING.
$route = '#^' . $query . '$#';
// CHECK FOR NUMERIC ROUTE
$route = preg_replace( '/\<\#(.*?)\>/', '(?P<\1>[0-9]+)', $route );
// CHECK FOR ALPHA NUMERIC ROUTE
$route = preg_replace( '/\<\:(.*?)\>/', '(?P<\1>[A-Za-z0-9\-\_]+)', $route );
if( preg_match( $route, $query, $matches ) )
{
return $route;
}
return false;
}
?>
Toevoeging op 09/09/2013 23:45:31:
Probleem is opgelost.
Ik match de query met de query, maar ik moet natuurlijk de query matchen met de route.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?
public function match( $query )
{
// ADD EXPESSION FOR MATCHING.
$route = '#^' . $this->_pattern . '$#';
// CHECK FOR NUMERIC ROUTE
$route = preg_replace( '/\<\#(.*?)\>/', '(?P<\1>[0-9]+)', $route );
// CHECK FOR ALPHA NUMERIC ROUTE
$route = preg_replace( '/\<\:(.*?)\>/', '(?P<\1>[A-Za-z0-9\-\_]+)', $route );
if( preg_match( $route, $query, $matches ) )
{
return $route;
}
return false;
}
?>
public function match( $query )
{
// ADD EXPESSION FOR MATCHING.
$route = '#^' . $this->_pattern . '$#';
// CHECK FOR NUMERIC ROUTE
$route = preg_replace( '/\<\#(.*?)\>/', '(?P<\1>[0-9]+)', $route );
// CHECK FOR ALPHA NUMERIC ROUTE
$route = preg_replace( '/\<\:(.*?)\>/', '(?P<\1>[A-Za-z0-9\-\_]+)', $route );
if( preg_match( $route, $query, $matches ) )
{
return $route;
}
return false;
}
?>
Toevoeging op 10/09/2013 00:11:10:
Wat ik nu nog mis is een Registry zoals hier http://phpro.org/tutorials/Model-View-Controller-MVC.html wordt beschreven.
Zouden jullie dit op de zelfde manier doen? Of is het een slecht voorbeeld?
Kan ja, maar ik ben zelf niet een groot fan van singletons (db::getInstance()). Google anders eens op dependency injection container. Daar is al veel over geschreven op het gebied van php. http://pimple.sensiolabs.org/ vind ik persoonlijk een erg sterk voorbeeld. Goede uitleg staat ook hier http://fabien.potencier.org/article/11/what-is-dependency-injection
Wat stel jij dan voor?
Verder had ik nog een vraagje over wanneer er geen route gevonden is.
Is het logisch om dan in de FrontController te bepalen dat er geen route gevonden is en dan een conytollrt aan te roepen die bijvoorbeeld een 404 error geeft?
De router is toch verantwoordelijk voor alle routes, het lijkt mij dus toch logisch om daarvoor een default route te maken?
Verder had ik nog een vraagje over wanneer er geen route gevonden is.
Is het logisch om dan in de FrontController te bepalen dat er geen route gevonden is en dan een conytollrt aan te roepen die bijvoorbeeld een 404 error geeft?
De router is toch verantwoordelijk voor alle routes, het lijkt mij dus toch logisch om daarvoor een default route te maken?
-
Gewijzigd op 12/09/2013 19:59:18 door Tom Swinkels




