pagina achter slash in URL

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Timo Bakker

Timo Bakker

22/11/2018 15:50:57
Quote Anchor link
Goedemiddag allemaal,

Ik heb wellicht een hele simpele vraag. Ik wil graag voor een website een actie pagina aanmaken. Je ziet ze wel eens voorbijkomen in de trant van 'www.domein.nl/actie ' zonder enige extensie erachter.

En dat is tevens mijn vraag, hoe krijg ik het voor elkaar dat ik een pagina kan maken, zonder direct .html of .php er aan toe te voegen, dat mensen direct op de bedoelde actie pagina komen?

Bij voorbaat dank voor jullie reactie,

Met vriendelijke groet,
Timo

Edit:
Topictitel aangepast van 'actie pagina' naar 'pagina achter slash in URL'
Gewijzigd op 22/11/2018 19:58:37 door - Ariën -
 
PHP hulp

PHP hulp

04/10/2024 08:10:35
 
Thomas van den Heuvel

Thomas van den Heuvel

22/11/2018 16:18:00
Quote Anchor link
Welkom in de wondere wereld van URL rewriting en routing.

TL;DR versie in het groen.

Wat er heel kort door de bocht moet gebeuren is het volgende: alle requests die naar jouw website worden gestuurd worden niet langer direct afgehandeld (omdat je rechtstreeks een PHP-script aanroept) maar het adres wordt eerst intern vertaald naar uit te voeren code, eventueel met extra parameters. Er vindt dus in feite een mapping van een externe URL naar een interne (applicatie-)URL plaats.

Een populaire manier om dit te doen is vaak door gebruikmaking van Apache's mod_rewrite module. Wat mensen dan vaak doen is *alles* mappen, oftewel, ze stellen een RewriteRule op (letterlijk een herschrijfregel van een externe naar een interne URL) voor ieder adres.

Dit wordt op den duur zeer bewerkelijk en foutgevoelig, en op een gegeven moment wordt dit ook een brei waarin de volgorde van deze RewriteRules een belangrijke rol gaat spelen, want op den duur wil je niet alleen exacte matches maar ook patronen gaan matchen waarbij je in wezen zegt "alles van de vorm X moet naar script Y doorgemapt worden".

Los van het feit dat je al deze regels in een .htaccess bestand moet stampen en je hele applicatie breekt (500 internal server errors) op het moment dat je ergens een fout maakt creëert dit een ander probleem: elke script vormt op dat moment een "voordeur" in jouw applicatie, dus eigenlijk worden al jouw PHP-bestanden afzonderlijke applicaties. Uit oogpunt van security is dat niet erg handig, want elk PHP-bestand zou dan uitgerust moeten worden met eenzelfde soort beveiliging wat op den duur bewerkelijk kan worden als je al deze bestanden up-to-date wilt houden. En als je hier niet heel erg consequent in bent is zo'n voordeur al snel een achterdeur :p.

Het zou dus veel beter zijn om een single point of entry (één enkel stuk code die het toegangspunt tot jouw applicatie vormt) in je applicatie te hebben. Dit heeft ten minste twee grote voordelen:
1. in eerste instantie kan je hele applicatie op één plek opgezet/geinitialiseerd/gebruiksklaar worden gemaakt. Dingen zoals security, database- en sessie-gebruik, het aanmaken van andere hulpobjecten etc. - volgens mij wordt dit ook wel het "bootstrappen" van de applicatie genoemd.
2. Dit punt (wat vaak neerkomt op index.php) kan vervolgens (als laatste stap na initialisatie) ook gebruikt worden om externe aanroepen te vertalen naar interne applicatie-calls. Hiermee heb je dus effectief de "routing" uit het eerdergenoemde externe bestand (.htaccess) binnen je applicatie getrokken en kun je hier de vertaling handmatig uitvoeren. Je hebt hier dan binnen je applicatie volledige controle over. De mapping kan vele vormen aannemen: van een simpel switch-statement naar het opvragen van een item uit een boomstructuur in je database tot het delegeren naar een andere controller voor het verder afhandelen van een request, er zijn legio mogelijkheden.

Het enige wat je dus (vervolgens) in wezen hoeft te regelen is het (intern) doorsturen van alle requests naar je single-point-of-entry. Vervolgens inspecteer je op deze plek het oorspronkelijke request ($_SERVER['REQUEST_URI']) en schrijf je code die de mapping verder afhandelt (of delegeert naar een ander stuk code die dit kan).

Zo zou je dus een externe aanroep van /actie kunnen laten resulteren naar het intern uitvoeren van /custom/actie.php.

Maar dan begint het eigenlijk pas :).

Om te voorkomen dat er conflicten ontstaan tussen de "virtuele" URL's en "fysieke" bestanden of directories met eenzelfde naam is het eigenlijk zaak dat je alle code verplaatst naar buiten je webdirectory om dit soort "botsingen" te voorkomen. Eigenlijk zou je publieke webdirectory dus enkel index.php moeten bevatten, en wat er verder publiek toegankelijk zou moeten zijn zoals CSS, afbeeldingen enzo.

En dan zou je ook eens na kunnen gaan denken over de verdere pagina-opbouw. Idealiter is /actie concreet niet een compleet HTML-bestand in de vorm van /custom/actie.php ofzo. Jouw website heeft vaak een vaste layout (het "maintemplate") en een variabel deel. Dat variabele deel heeft vaak een specifiek doel: een overzichtslijst, een zoekformulier of een artikel. Dit zou je dus als pagina-type kunnen programmeren. Uiteindelijk zou /actie dus kunnen verwijzen naar een of ander database-artikel dat weergegeven wordt door het artikel-pagina-type, misschien geconfigureerd met een wat gepimpt maintemplate om de actie er wat meer uit te laten springen.

Hierbij is er dus voor alle delen die hergebruikt worden aparte code geschreven zodat je je op den duur meer kunt gaan richten op de inhoud van je website, in plaats van dat je telkens het wiel opnieuw aan het uitvinden/uitdraaien bent.

Ondertussen begint de applicatie er steeds meer uit te zien als een soort van content management systeem (CMS).
Gewijzigd op 22/11/2018 18:10:45 door Thomas van den Heuvel
 
- Ariën  -
Beheerder

- Ariën -

22/11/2018 19:54:54
Quote Anchor link
Mijn .htaccess ziet er zo uit:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]

Alles wordt dus naar de index.php geschreven, tenzij het directories (-d) zijn of bestaande bestandsnamen (-f).

Op de index.php kan je met parse_url de URL uitsplitsen tot in een array.
Thomas heeft er ooit een artikeltje/snippet over geschreven:
Gewijzigd op 22/11/2018 19:55:27 door - Ariën -
 
Timo Bakker

Timo Bakker

23/11/2018 14:45:25
Quote Anchor link
Dank Thomas en Ariën,

dank voor jullie reactie. Het werkt, maar wat mij opvalt, is dat het absoluut niet uitmaakt welk woord je gebruikt om naar de index.php file omgeleid te worden. In mijn geval, laat ik bezoekers www.domein.nl/actie in de browser invoeren, maar dat had net zo goed 'pekingeend' kunnen zijn i.p.v. 'actie'. Je komt altijd op de index.php pagina. Klopt dat?

gr. Timo
 
- Ariën  -
Beheerder

- Ariën -

23/11/2018 14:51:33
Quote Anchor link
Klop! In de genoemde voorbeeldcode wordt nergens een beperking over de beschikbare woorden ingesteld.
In je index.php moet je dit zelf regelen. Ikzelf heb ooit voor een CMS een simpele procedure geschreven die kijkt of een bestand als .php extentie in een bepaalde map bestaat, plus een white-list in een array.

Als er een niet bestaande waarde wordt opgeroepen, geef ik een foutmelding met 404 Not Found header..
Gewijzigd op 23/11/2018 14:52:30 door - Ariën -
 
Thomas van den Heuvel

Thomas van den Heuvel

23/11/2018 16:17:15
Quote Anchor link
Dit maakt inderdaad niets uit, alle requests worden bij de voordeur van je applicatie (index.php) afgeleverd. Het is dan dus wel zaak om onderscheid te maken tussen bestaande en niet-bestaande pagina's. Vooral als je tools gebruikt om bezoek te volgen (zoals bijvoorbeeld Google Analytics), anders kan dit mogelijk de statistiek beïnvloeden, plus het is anders niet echt duidelijk naar de eindgebruiker toe.

Elke webapplicatie zou (en heeft meestal ook) een 404 Page Not Found pagina moeten hebben. Zo kun je bezoek terugsturen naar de bewoonde wereld. Sommige sitebouwers geven hier ook nog een creatieve draai aan.

Het eindresultaat van de "berekening van de pagina" (het omzetten van de externe URL naar de interne URL) levert dus tevens altijd het resultaat "gevonden" (de aanroep was een geldige aanroep en de bijbehorende pagina werd gevonden) of "niet gevonden" (de aanroep was niet geldig) op.

Stel dat jouw website ook afgeschermde delen heeft waarvoor je een login nodig hebt, en je navigeert hier naartoe zonder dat je je hebt aangemeld zou je ook net kunnen doen of deze pagina niet bestaat. Ik heb eigenlijk niet echt goede argumenten voor of tegen deze aanpak gehoord maar uit oogpunt van security lijkt mij dit niet verkeerd, je geeft immers niet met veel toeters en bellen aan dat je onvoldoende rechten hebt om die pagina te mogen bekijken, je doet simpelweg alsof deze niet bestaat en geeft daarmee dus geen ruchtbaarheid aan het bestaan van een beveilighde pagina.

Het lijkt mij altijd het beste om expliciet te zijn in het gedrag van een webpagina, ook al is iets mogelijk soms al default gedrag.

Zo zou ik een "gevonden" HTML pagina altijd voorzien van een 200 OK status code header. En je zult dus de pagina's die volgens jou niet bestaan altijd moeten flaggen als 404 Not Found. Dit doe je met de header() functie. Deze moet aan de webpagina worden meegegeven nog voordat er data van die pagina is verstuurd. Hier komt dus wederom naar voren/boven dat je bij het in elkaar schroeven van een dynamisch gegenereerde pagina na moet gaan denken over hoe je dat structureel aanpakt, dus ook hoe je deze (op protocol niveau) opzet en verstuurt.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.