Door
Mark Hogeveen
op 06-12-2013 15:46
gewijzigd op 06-12-2013 15:49
11.712 views
Hallo, misschien een erg simpele vraag.
Bij routing voor je website stuur je eigenlijk alle requests door naar 1 pagina. Meestal index.php.
Doe je dan dus ook de POST data daarnaartoe sturen? En hoe doe je die dan weer doorgeven aan de juiste controller?
En hoe doe je alle get variabelen verwerken? Doe je dan iets als $_GET[0], $_GET[1] etc?
Ik begrijp niet echt wat het voordeel is van een router. Je moet telkens de juiste controllers/models/vieuws includen, soms (volgens mij) onnodig een header gebruiken om een gebruiker door te sturen naar de juiste locatie.
Daarnaast lijkt me het controleren van GET variabelen moeilijker, alles doe je rewriten naar mooie URL's,
Dus dit: www.site.nl/help.php?action=view&item=10023 wordt dit: www.site.nl/help/view/10023
Aan de tweede url zou je niet meer kunnen zien of view een map is, of (de waarde van) een veriabale.
Niet dat dit voor buitenaf belangrijk is, of dat bezoekers hier iets mee moeten. Maar hierdoor lijkt het me verwarrend. Ook zou ik niet weten wat ik moet doen als een pagina direct wordt aangeroepen, dus niet door de router, maar rechtstreeks (zonder include, en dus zonder code die in de router eventueel erboven zou staan, voor het include statement)
Een error 404 geven is dan eigenlijk liegen, doorsturen naar de router en zo een omweg maken lijkt me ook raar.
Ik bedoel dat ik ik het vreemd vind overkomen dat je in de public map een index.php bestand hebt en je daarin een require uitvoert naar een private index.php ..
Zelf plaats ik alleen maar mijn index.php, css, js en images in de public directory.
Voor de rest staat alles in de de root directory, maar ik require / include geen bootstrap file, alleen de autoloader die de applicatie start
Ik zie niet wat er raar aan is hoor? Waarschijnlijk staan de dingen die jij dan in je public index.php hebt staan bij mij in de private index.php. Dat is waars. het enige verschil. Ik heb bewust zo min mogelijk code in mijn public index.php staan. Alles staat dan veilig op een plek waar niemand er van buitenaf bij kan.
Maar wat maakt het uit als er iemand een request doet naar een script, dat geen output geeft, maar wel wordt gebruikt om bijvoorbeeld te includen.
Je hebt dan toegang tot de "pagina" (het script) maar dat is toch niet onveilig?
Het enigste dat iemand dan zou kunnen proberen is bepaalde input geven met POST of GET requests, maar als je daar rekening mee houdt kan er niks gebeuren toch?
Het is natuurlijk wel logisch om dit soort scripts af te schermen.
Een voorbeeld (niet echt mvc, maar als voorbeeld)
contact.php (formulier etc.)
<?php
if($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['send'])) {
// require het bestand om het formulier te verwerken
require "ContactController.php";
}
?>
<!-- Form stuurt data naar huidige pagina -->
<form method="post" action="">
Bericht: <textarea name="msg"></textrea>
<input type="submit" name="send" value="Verzend" />
</form>
Als je nu ContactController rechtstreeks zou aanroepen via de browser, zou je een lege pagina krijgen. ContactController denkt dat er een formulier is verzonden, en wil een niet-verzonden formulier verwerken.
Dat zou dus een fout kunnen veroorzaken.
Of stel dat je PHP server er een keer uitklapt dan zijn al je bestanden voor de complete buitenwereld zichtbaar en weet iedereen precies hoe je code in elkaar zit.
Maar goed, je moet het vooral zelf weten. Het was een goed bedoelde tip. Wat je ermee doet laat ik helemaal aan jou over.
Nee, heel erg bedankt dat er mensen zijn die mij hierop wijzen!
Van de reactie van Wouter J schrik ik een beetje. Tools waarmee je de PHP scripts kunt zien? Lekker dan... Ik dacht dat dit vrijwel onmogelijk is, dat je dat alleen kon als je echt toegang had tot het FTP.
En wat Ozzie zegt: ik begrijp dus dat als de PHP server eruit ligt, dan wordt de PHP code dus niet meer geparst (logisch) en dus wordt het als plain tekst/html gestuurd naar de client (ook logisch).
Nu toch nog een vraag, na 4 dagen.
Bij een router heb je dus de map en bestandsnamen in een GET variabele staan.
site.nl/public/page.php?item=1234 rewrite je naar site.nl/page/item/1234
Door dit rewriten raak ik juist door de war. Is het voor mij misschien verstandiger, om eerst helemaal niet te kijken naar het herschrijven van URL's, en gewoon eerst eens met niet-herschreven URL's te werken?
Dan komt dat rewriten wel vanzelf?
>> ik begrijp dus dat als de PHP server eruit ligt, dan wordt de PHP code dus niet meer geparst (logisch) en dus wordt het als plain tekst/html gestuurd naar de client (ook logisch).
Inderdaad, en als je niet ervoor hebt gezorgd dat directories worden afgeschermd zijn al je bestanden ook nog eens zichtbaar. Daarom wil je bestanden die code bevatten dus niet in je public directory hebben staan.
>> Door dit rewriten raak ik juist door de war. Is het voor mij misschien verstandiger, om eerst helemaal niet te kijken naar het herschrijven van URL's, en gewoon eerst eens met niet-herschreven URL's te werken?
Nee, dat zou ik niet doen. Ik zou juist zorgen dat je het principe snapt, om jezelf achteraf een hoop werk en frustraties te besparen ;)
Hoe het in de details werkt ga ik je nu niet uitleggen, maar het principe is in hele grote lijnen als volgt.
URL: jouwsite.nl/fotoalbum/toon/5
Deze URL wordt opgevangen door jouw index.php in de public map en stuur je door naar de index.php in de private map (ook wel bootstrap genoemd). Uiteindelijk komt deze URL in een router terecht en wordt deze opgesplitst in:
- fotoalbum
- toon
- 5
Deze "route" wordt gematched met een controller (de FotoAlbumController) en een actie (de toonAction), waarbij 5 het nummer is van de foto die moet worden getoond.
Dit is even een heel globale uitleg die wellicht een kwartje doet laten vallen ;)
Of kijk gewoon eens naar een simpele tool als silex. Die toont op een simpele manier hoe je omgaat met routing, etc. Het biedt vele integratie mogelijkheden met andere libraries en je hebt nog steeds bijna alles in de hand!
Ik heb heel wat geƫxperimenteerd. Mij vallen 2 verschillende soorten manieren van routing op.
- Routen met alle mogelijke URL's in een lijst, een soort register van alle pagina's dus.
- De URL's niet opslaan in een lijst, maar gewoon uit de URL zelf de informatie halen.
De eerste manier lijkt me het handigst, volgens mij doet Symfony het ook zo. Het nadeel is wel dat je een configuratie moet maken waar je soms dus heel veel routes moet definiƫren.
De tweede manier vind ik minder, in sommige gevallen worden de routes nog steeds bepaald door de bestandsnamen van files. Dus als je een file hebt die contactPage.php heet, dan zou de route eruit zien als /contactPage/ terwijl je dit zou willen: /contact/
Je moet dan de naam van het bestand of controller o.i.d veranderen.
Terwijl routing juist onafhankelijk van bestandsnamen moet zijn.