[PHP/Mod_Rewrite] Clean Urls

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • X_lawl_X
  • Registratie: September 2009
  • Laatst online: 16:13
Hey,

Ik heb een probleem met mod_rewrite. Mijn sites zijn allemaal op een modulaire manier opgebouwd. Ik heb een mapje met core files, waarin de basis scripts instaan die je vrijwel op iedere site nodig zou hebben, en een mapje modules, waarin ik, zoals de naam al zegt, modules kan wegzetten.

Als het bestand index.php wordt geladen, haalt het alle actieve modules op uit de database waar de gebruiker toegang tot heeft, en stopt de informatie in een array. Deze array ziet er ongeveer zo uit.

PHP:
1
2
3
4
$m['user/login']    = array (
                    'file'  => 'login.php',
                    'menu_item' => 'Log In',
                    );


Als de gebruiker index.php?p=user/login bezoekt, wordt eerst gekeken of de array $m['user/login'] bestaat. Is dit zo, dan wordt de login module geladen.

Dit heb ik met mod_rewrite wat aangepast, zodat de URL er wat mooier uitziet. De gebruiker kan nu deze module bezoeken door naar domein.nl/user/login te gaan.

Dit systeem werkt goed, tenzij ik met modules werk die $_GET variabele nodig hebben. In dit soort gevallen wordt de URL meer iets van domein.nl/showpost?id=1&cat=index. Ik kan hier maar een paar dingen voor bedenken, om dit ook er mooier uit te laten zien.
  1. Voor iedere module die dit soort argumenten nodig heeft, een extra rewrite rule zetten in .htaccess
  2. Het path exploden op '/', kijken of de array meer dan bv. 2 waarde bevat, de eerste 2 waarden beschouwen als path, en de overige als argumenten voor de module en die doorsturen.
Aan beide methoden zit een nadeel. Ik geloof dat er een veel makkelijkere manier is dan voor iedere module .htaccess aan te passen, en manier 2 zie ik helemaal niet zitten voor het geval dat je een module hebt met een path als hoi/foo/bar.

Ik kan op dit moment geen andere manier bedenken om dit op te lossen, als ik er op google kom ik alleen maar tutorials tegen hoe je mod_rewrite moet gebruiken. Kan iemand mij dus een zetje in de goede richting geven? :)

Acties:
  • 0 Henk 'm!

Verwijderd

Je kunt toch gewoon alles naar index.php rewriten, en vanaf daar dispatchen/routen naar de juiste module.
En als je dan get variabelen nodig bent doe je:
domein.nl/showpost?id=1&cat=index

Acties:
  • 0 Henk 'm!

  • X_lawl_X
  • Registratie: September 2009
  • Laatst online: 16:13
Ik zoek dan meer iets als domein.nl/showpost/1/index.

offtopic:
Uiteraard bedoelde ik ook domein.nl/showpost?id=1&cat=index in mijn topic :+

[ Voor 50% gewijzigd door X_lawl_X op 26-05-2010 19:11 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Ik begreep je volgens mij verkeerd. Wat ik bedoel is alles rewriten naar index.php (dus niet naar index.php?p=user/login maar gewoon naar index.php) , en dan naar $_SERVER['REQUEST_URI'] kijken om naar de juiste module te dispatchen. De $_GET variabelen kun je dan gewoon vanaf blijven (en gebruiken zoals je gewend bent).

Edit: dus deze rewriterules:
RewriteCond %{REQUEST_URI} !^\/_static/(.*)$
RewriteCond %{REQUEST_URI} !^\/index.php$
RewriteRule ^(.*)$ index.php [L]
Alles rewriten naar index, met als uitzondering een _static mapje om layout afbeeldingen en css enzo in te hosten (en natuurlijk index.php zelf als uitzondering om een oneindige loop te voorkomen).

Zo is hoe ik het wel eens opgelost heb.

[ Voor 44% gewijzigd door Verwijderd op 26-05-2010 19:19 ]


Acties:
  • 0 Henk 'm!

  • X_lawl_X
  • Registratie: September 2009
  • Laatst online: 16:13
Bedankt voor je reply ;)

Als ik dit doe, en ik heb in een module $id nodig, dan heb ik nog steeds een probleem.

>De gebruiker gaat naar /foo/bar/34
>Het is de bedoeling dat de module foo/bar wordt opgehaald, en er iets met id 34 gedaan wordt.

In plaats daarvan, wordt module foo/bar/34 opgehaald, wat een 404 zal geven omdat deze module niet bestaat. :/

Acties:
  • 0 Henk 'm!

Verwijderd

Ja sorry hoor, maar dat hangt dan vooral af van of jij kunt programmeren of niet. Ik zie echt geen enkel probleem.

Acties:
  • 0 Henk 'm!

  • dev10
  • Registratie: April 2005
  • Laatst online: 09-09 15:21
Een kleine tip: http://www.php.net/explode. Verder is het precies zoals Cheatah al zegt, er is niet echt een probleem behalve dat je wat basiskennis PHP mist. (Niet lullig bedoeld natuurlijk. ;))

Nu ik nog een keer naar je 'probleem' kijk, denk ik dat je misschien met preg_split wat makkelijker kunt werken als je overweg kunt met reguliere expressies. Dan kun je namelijk splitten op alles wat voor het getal staat.

[ Voor 100% gewijzigd door dev10 op 26-05-2010 19:41 ]


Acties:
  • 0 Henk 'm!

Verwijderd

X_lawl_X schreef op woensdag 26 mei 2010 @ 19:32:
Bedankt voor je reply ;)

Als ik dit doe, en ik heb in een module $id nodig, dan heb ik nog steeds een probleem.

>De gebruiker gaat naar /foo/bar/34
>Het is de bedoeling dat de module foo/bar wordt opgehaald, en er iets met id 34 gedaan wordt.

In plaats daarvan, wordt module foo/bar/34 opgehaald, wat een 404 zal geven omdat deze module niet bestaat. :/
Ja dan kom je dus uit op foo/bar?id=34 he... Of je moet een systeem bedenken met statische routes met parameters in de database ofzo.

Edit: Je kunt trouwens ook eens naar het zend framwork kijken (of je het kunt gebruiken, of hoe ze het daar hebben opgelost). En dan voor jouw 'probleem' voornamelijk naar de front controller, dispatcher, standard router etc.

[ Voor 16% gewijzigd door Verwijderd op 26-05-2010 19:44 ]


Acties:
  • 0 Henk 'm!

  • dev10
  • Registratie: April 2005
  • Laatst online: 09-09 15:21
Verwijderd schreef op woensdag 26 mei 2010 @ 19:40:
[...]

Ja dan kom je dus uit op foo/bar?id=34 he...
Nee, aangezien die rewrite alles doorstuurt naar index.php, dus ook ?id=34. Je zult de request URL op een of andere manier uit elkaar moeten trekken. (Al was het alleen maar omdat de TS een nette url wil. Dan lijkt het mij dat hij geen ?id=34 in z'n URL wil hebben.)

Acties:
  • 0 Henk 'm!

  • X_lawl_X
  • Registratie: September 2009
  • Laatst online: 16:13
dev10 schreef op woensdag 26 mei 2010 @ 19:38:
Een kleine tip: http://www.php.net/explode. Verder is het precies zoals Cheatah al zegt, er is niet echt een probleem behalve dat je wat basiskennis PHP mist. (Niet lullig bedoeld natuurlijk. ;))

Nu ik nog een keer naar je 'probleem' kijk, denk ik dat je misschien met preg_split wat makkelijker kunt werken als je overweg kunt met reguliere expressies. Dan kun je namelijk splitten op alles wat voor het getal staat.
offtopic:
Ik wist al van explode() af. *wijst naar oplossing 2 van OP*. Het probleem is niet dat ik niet genoeg basiskennis van PHP heb [denk ik zelf :+], maar dat ik niet goed weet hoe ik het moet aanpakken.


Ik kan overweg met regex, ik zal ik kijken of het daarmee lukt. Al heb ik nog steeds het gevoel dat er een makkelijkere manier was.

De URL moet er inderdaad uitzien net zoals de URL's hier op GoT - geen enkele &id= of zoiets.

[ Voor 14% gewijzigd door X_lawl_X op 26-05-2010 19:49 ]


Acties:
  • 0 Henk 'm!

Verwijderd

dev10 schreef op woensdag 26 mei 2010 @ 19:44:
[...]


Nee, aangezien die rewrite alles doorstuurt naar index.php, dus ook ?id=34. Je zult de request URL op een of andere manier uit elkaar moeten trekken. (Al was het alleen maar omdat de TS een nette url wil. Dan lijkt het mij dat hij geen ?id=34 in z'n URL wil hebben.)
Ja dat zeg ik. Met die aanpak die ik hierboven had voorgesteld zit je dan vast aan ?id=34 gebruiken (dat zit dan gewoon in de $_GET dus dat kun je dan in de module gebruiken). Als je dat niet wil zul je een 'ingewikkelder' systeem moeten bedenken.
Routes aanmaken in de database dus, of als je van een MVC-achtig systeem gebruik maakt gewoon standaard naar /{module}/{controller}/{action} dispatchen en de rest van de parameters doorsturen naar de module:
Module + controller + action + params:
http://example/blog/archive/list/sort/alpha/date/desc
module == blog
controller == archive
action == list
sort == alpha
date == desc
Ofzo.... Er zijn tig oplossingen te bedenken.

Edit: leesvoer: http://framework.zend.com...nd.controller.router.html Misschien wat overkill voor jouw situatie maar over de meeste dingen in het Zend-Framework is wel nagedacht.

[ Voor 19% gewijzigd door Verwijderd op 26-05-2010 20:01 ]


Acties:
  • 0 Henk 'm!

  • X_lawl_X
  • Registratie: September 2009
  • Laatst online: 16:13
Verwijderd schreef op woensdag 26 mei 2010 @ 19:51:
[...]of als je van een MVC-achtig systeem gebruik maakt gewoon standaard naar /{module}/{controller}/{action} dispatchen en de rest van de parameters doorsturen naar de
Dat ik hier niet eerder op ben gekomen |:(

Ik denk dat ik eerst de $_SERVER['REQUEST_URI'] explode, dan met array_shift(); de module, controller en action eruithaal. Wat er dan overblijft kan ik dan doorsturen.

Ik zal morgen wel wat in elkaar zetten. Bedankt voor jullie hulp.

Acties:
  • 0 Henk 'm!

  • bindsa
  • Registratie: Juli 2009
  • Niet online
X_lawl_X schreef op woensdag 26 mei 2010 @ 22:46:
[...]


Dat ik hier niet eerder op ben gekomen |:(

Ik denk dat ik eerst de $_SERVER['REQUEST_URI'] explode, dan met array_shift(); de module, controller en action eruithaal. Wat er dan overblijft kan ik dan doorsturen.

Ik zal morgen wel wat in elkaar zetten. Bedankt voor jullie hulp.
Als je met 'doorsturen' header redirects o.i.d. bedoelt dan moet je oppassen voor SEO, crawlers vinden veel redirects namelijk niet zo leuk :+

Acties:
  • 0 Henk 'm!

  • Spiked
  • Registratie: Mei 2008
  • Laatst online: 24-07 14:50
Of je gebruikt (simpele) reguliere expressies voor je routes; user/profile/[0-9]+

Acties:
  • 0 Henk 'm!

  • X_lawl_X
  • Registratie: September 2009
  • Laatst online: 16:13
L0calh0st schreef op donderdag 27 mei 2010 @ 09:44:
[...]


Als je met 'doorsturen' header redirects o.i.d. bedoelt dan moet je oppassen voor SEO, crawlers vinden veel redirects namelijk niet zo leuk :+
Ik bedoelde met doorsturen het doorsturen van de rest van de array naar de module, niet redirecten :+
Pagina: 1