[php] MVC-router / Mod_rewrite

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
goedemiddag,

ik ben een tijdje bezig met een MVC en loop even ergens tegen aan, n.l. de consistentie/afhandeling van de router
Stel ik heb een tabel met CD's (id, albumtitel, artiest, releasedatum etc.)

Om een lijst van cd's te genereren maak ik dan gebruik van een router index.php?route=cd/getAll
Vervolgens kan ik in de lijst sorteren (artiest -oplopend), de router wordt dan index.php?route=cd/getAll/artiest/ASC

Stel dat ik een 2 sortering wil aanbrengen, eerst op artiest - oplopend, en vervolgens releasedatum - oplopend dan zou dat bijv. worden -> index.php?route=cd/getAll/artiest/ASC/releasedatum/ASC
Anderzijds zou ik willen filteren op releasedatum 01-01-2009 - > index.php?route=cd/getAll/artiest/ASC/releasedatum/01-01-2009

Ik heb dus steeds een andere controller krijg niet helder hoe ik deze controller moet afhandelen.
Hoe kijken jullie hier tegenaan?

Hetzelfde geldt in feite voor een mod_rewrite.

[ Voor 3% gewijzigd door Verwijderd op 23-01-2009 12:34 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Het lijkt me dat je steeds dezelfde controller, model en view gebruikt. Je wilt immers steeds hetzelfde doen, namelijk het weergeven van CD's. Het enige wat verschilt is namelijk op welke wijze je de CD's weergeeft. In feite dus welke data je op welke wijze in de view stopt.

Je geeft dus geen, 1 of meerdere parameters mee aan de controller (althans je zorgt dat ze daar komen). Aan jouw controller om te zorgen dat bepaalde data in de view terecht komt. Je hebt, ik noem het even dom de GeefCdWeerController. Zonder parameters zorgt deze controller dat de view alle cd's op alfabet weer geeft. Met parameters geeft de view dus dezelfde data anders gesorteerd weer.

[edit: Wat betreft mod_rewrite. Wat ik doe, maar wat ongetwijfeld niet de enige optie is, is alles door index.php laten lopen. Index.php doet weinig meer dan een Router object instantieren welke op zijn beurt module, controller en eventueel acties aanroept. Alle overige argumenten in de url example.com/module/controller/actie/sorteer/asc zijn dat dan sorteer en asc worden gebruikt om nadere acties te specificeren. example.com/assets/cds/weergeven/sorteer/asc zou dan een logische url worden.]

[ Voor 51% gewijzigd door Verwijderd op 23-01-2009 13:49 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Verwijderd schreef op vrijdag 23 januari 2009 @ 12:33:
Ik heb dus steeds een andere controller krijg niet helder hoe ik deze controller moet afhandelen.
Foutje mijn kant, ik heb dus wel steeds dezelfde controller nl. 'GeefCdWeerController'.
echter de hoeveelheid en typen parameters vanuit mijn router is onbekend.

index.php?route=cd/GeefCdWeerController/artiest/ASC/
levert de volgende query: 'SELECT FROM artiest ORDER BY artiest ASC'

index.php?route=cd/GeefCdWeerController/releasedatum/01-01-2009
levert de volgende query: 'SELECT FROM artiest WHERE releasedatum = 01-01-2009

index.php?route=cd/GeefCdWeerController/albumtitel/Bestof/releasedatum/01-01-2009/artiest/ASC
levert de volgende query: 'SELECT FROM artiest WHERE releasedatum = 01-01-2009 AND albumtitel = Bestof ORDER BY artiest ASC'

Hoe ga je met deze verschillende routers om?

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Eigenlijk hoeven het geen verschillende routes te zijn. Een route is alleen een manier om op te schrijven dat je een bepaald patroon bij een bepaalde controller uit wilt laten komen. Je kunt dus in de routes ook wildcards definieren voor de parameters. De controller vogelt dan verder zelf uit hoe deze parameters vertaald worden naar een query aan je model. Dat is ook veel handiger, want dan hoef je alleen maar je controller aan te passen als je er nieuwe zoekmogelijkheden bij krijgt, niet ook nog je routes.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • mocean
  • Registratie: November 2000
  • Laatst online: 04-09 10:34
je hoeft niet per se alles via een rewrite te doen he. je kan volstaan met een hoofroute als:

/cd/search/&artistsort=asc&release=01-01-2009

Als je een Table hebt met 10 kolommen, en je gaat multi-sorten en zoeken, dan is alles rewriten een ramp. Als het voor Google niet interessant is dat sorteren, kan je het ook met POST afhandelen (knoppen)

Koop of verkoop je webshop: ecquisition.com


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@drm:

bedoel je hiermee dat ik altijd dezelfde structuur kan aanhouden?

bijv.
index.php?route=cd/GeefCdWeerController/*/*/artiest/asc/3
$args[0] = * ;
$args[1] = * ;
$args[2] = artiest;
$args[3] = asc;
$args[4] = 3;

respectievelijk
FILTER
FILTERVALUE
ORDERBY
ODERBYVALUE
PAGINA

hetgeen ik doorgeef aan mij query?
Nog helemaal niet aan gedacht... 8)7

@mocean:
da's natuurlijk ook een goede optie, moet ik wel even uitzoeken hoe ik dit moet afhandelen in mijn router.

[ Voor 14% gewijzigd door Verwijderd op 23-01-2009 15:56 ]


Acties:
  • 0 Henk 'm!

Verwijderd

mocean schreef op vrijdag 23 januari 2009 @ 15:47:
je hoeft niet per se alles via een rewrite te doen he. je kan volstaan met een hoofroute als:

/cd/search/&artistsort=asc&release=01-01-2009

Als je een Table hebt met 10 kolommen, en je gaat multi-sorten en zoeken, dan is alles rewriten een ramp. Als het voor Google niet interessant is dat sorteren, kan je het ook met POST afhandelen (knoppen)
Je kan ook niets rewriten maar simpelweg alles doorsturen naar index.php behalve bestaande files en mappen. Dan kan je daar lekker de url parsen.

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

quibuz:
@drm:

bedoel je hiermee dat ik altijd dezelfde structuur kan aanhouden?

bijv.
index.php?route=cd/GeefCdWeerController/*/*/artiest/asc/3
$args\[0] = * ;
$args\[1] = * ;
$args\[2] = artiest;
$args\[3] = asc;
$args\[4] = 3;

respectievelijk
FILTER
FILTERVALUE
ORDERBY
ODERBYVALUE
PAGINA
Nee andersom, je geeft in je route op de een of andere manier aan dat je na cd/GeefCdWeerController de rest ook wilt matchen, dus cd/GeefCdWeerController/*
Alles wat dan op de plek van de * komt (ongeacht het voorkomen van slashes) kan dan als "searchParams" o.i.d. aan de controller meegegeven worden. Of je het dan vervolgens in slashes split of iets anders moet je zelf weten.

Je kunt het ook met gewone querystring parameters doen zoals mocean zegt. Voor de goede orde hoef je dan dus niks meer in je router af te vangen, je kunt de controller laten besluiten wat 'ie met de parameters doet.

Het lijkt overigens alsof je een mvc framework gebruikt. Welke is dat? Zend, cake, symfony?

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
drm schreef op vrijdag 23 januari 2009 @ 18:07:
[...]
Alles wat dan op de plek van de * komt (ongeacht het voorkomen van slashes) kan dan als "searchParams" o.i.d. aan de controller meegegeven worden. Of je het dan vervolgens in slashes split of iets anders moet je zelf weten.
In genoemd geval (index.php?route=cd/getAll/artiest/ASC/releasedatum/ASC) werk ik met de volgende structuur:
CD is de folder van de controller
getAll is de betreffende controller
Alles daarna wordt als argument meegegeven aan de controller
Dat is dus in feite wat je benoemt...
Probleem waar ik dus mee zit is dat ik eigenlijk op zoek ben naar een vaste structuur voor de argumenten.. anders weet mijn controller niet meer wat ie met de argumenten moet doen.
drm schreef op vrijdag 23 januari 2009 @ 18:07:
[...]
Je kunt het ook met gewone querystring parameters doen zoals mocean zegt. Voor de goede orde hoef je dan dus niks meer in je router af te vangen, je kunt de controller laten besluiten wat 'ie met de parameters doet.
Die combinatie klinkt wel prettig.... een vaste structuur voor een aantal argumenten, overige argumenten dan als gewone querystring parameter.
drm schreef op vrijdag 23 januari 2009 @ 18:07:
[...]
Het lijkt overigens alsof je een mvc framework gebruikt. Welke is dat? Zend, cake, symfony?
MVC idd, maar ik ben niet zo van het beproefde concept toepassen... ik probeer obv tutorials zelf wat te bouwen en snappen.
Kost me altijd veel meer tijd en is half zo goed.. maar vaak 2x zo leuk , en ik hoop dat ik t dan begrijp ;)

Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Waarom doe je dit niet gewoon met een POST of GET parameter ?

Op het moment dat je informatie gaat verzenden naar het web om bijv. de state van een pagina te veranderen hoor je een POST of GET te gebruiken.

In dit geval wordt jouw pagina dus cd/getall/artiest/ <-- base pagina voor die artiest
Dan ga je verder filteren met POST om bijv. te zoeken binnen die artiest zijn discography, en get's naar dezelfde pagina om deze te sorteren op releasedatum, wat dan ook.

Zou best een zooitje worden in google als iedereen zo zou werken als jij hierboven bedoelt...

bekijk voor de gein eens hoe de URL structuur van GOT. daar zie je ook dat niet voro elke actie een url parameter gebruikt wordt :)

[ Voor 24% gewijzigd door SchizoDuckie op 23-01-2009 22:01 ]

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@ duckie..

het voorstel van mocean dus?
index.php?route=cd/getAll/Orbital/2/&release=01-01-2009

oftewel getAll van Orbital, pagina 2
Get-waarde release is dan filter.

Zit ik met bovenstaande wel ff met de volgende vraag:

Ik werk nu als volgt: ik split de route op slashes.
Alles na de controller zijn nu argumenten die ik meegeef aan de controller.
Wordt die &release gewoon als GET gelezen of als een van de argumenten?

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Volgens mij denk je veel te moeilijk. Zoiets is al voldoende:
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
42
function isValidController($controllerName) {
    // zoek uit of $controllerName een geldige controller is
}

function isValidAction($controllerName, $action) {
   // zoek uit of $action een geldige action voor controller $controllerName is.
}

function dispatchRoute($route) {
   $controllerClass = ucfirst($route['controller']) . 'Controller';
   $action = $route['action'] . 'Action';
   $controllerInstance = new $controllerClass ();
   
   return call_user_func(array($controllerInstance, $action), $route);
}

function parseRoute($route, $defaultRoute) {
   $ret = $defaultRoute;
   $args = explode('/', trim($route, '/'));
   if(isset($args[0]) && isValidController($args[0])) {
      $ret['controller'] = $args[0];
      if(isset($args[1]) && isValidAction($ret['controller'], $args[1])) {
         $ret['action']= $args[1];
         if(isset($args[2])) {
             $ret['remainder'] = $args[2];
         }
      }
   }
}

$defaultRoute = array (
   'controller' => 'index',
   'action' => 'index',
   'params' => $_REQUEST,
   'remainder' => null
);

if(isset($_GET['route'])) {
   $route = parseRoute($_GET['route'], $defaultRoute);
}

dispatchRoute($route);

(uit de losse pols, gaat even om het voorbeeld). In feite ben je er dan al. Of je de parseRoute dan nog andere parameters uit de route laat halen kun je dus algemeen maken door daar een standaardformat voor te verzinnen, maar dat hoeft niet, je kunt dat ook aan de controller overlaten.

De beste leerschool voor dit soort dingen is -naast het zelf maken- ook vooral kijken hoe anderen het gedaan hebben, dus kijk eens naar oa. cake, symfony en zend framework om te zien hoe zij een MVC pattern met routing doen.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz

Pagina: 1