2008. január 23., szerda

Beszédes URL-ek .htaccess, mod_rewrite azaz a rewrite engine ereje 1.

Nagyon sokan rá vannak kattanva az úgynevezett "beszédes URL"-ekre, amik kb. ilyenek:

http://blog.rhodeus.hu/2008/01/beszedes-url-ek-htaccess-modrewrite.html

Szimplán csak annyiról van szó, hogy a felhasználó által egyszerűbben megjegyezhető, mintha ugyanez ebben a formában lenne például:

http://blog.rhodeus.hu/?year=2008&month=01&day=14&entryID=28

De leginkább azért ajánlott, mert állítólag a google is jobban szereti, valamiért sokkal jobbak az indexelési statisztikák az előbbi URL-ekre, mint az utóbbiakra. Mindenesetre ebbe a részébe én most nem mennék bele, inkább lássuk, miből áll ez az egész.


Mint az már fentebb is írva volt, eme URL-ek megvalósításához szükségünk lesz egy .htaccess fájlra illetve a rewrite engine-re, és a mi esetünkben PHP-ra.
A Rewrite Engine célja kb., a kapott URL minták illeszkedése és adott feltételek (pl. reguláris kifejezések) teljesülése esetén az URL átírása.

Ez rövid konyhanyelven: Ha egy általunk meghatározott rewrite szabálynak megfelelő URL kérés érkezik a szerverhez, a webszerver a felhasználó tudta nélkül az általunk megszabott új formában továbbítja nekünk (vagy másnak :D).

pl.: a felhasználó ezt írja be: http://www.midomainunk.hu/filmek, de a szerver valójában ezt fogja futtatni: http://www.midomainunk.hu/index.php?oldal=filmek (a felhasználó ezt nem látja)

A .htaccess fájlba gyorsan véssük bele:

Nézzük soronként:

1.)
Egyszerű feltétel, azaz ebben a blokkban szereplő bejegyzéseket, csak akkor szeretnénk, ha értelmezné a webszerver, ha a rewrite modul be van töltve, különben hagyja az egészet figyelmen kívül.

2.) Elindítjuk a Rewrite modult, hogy használni tudjuk. Alapértelmezetten tiltva van.

3.) Lényegében ezzel a sorral azt mondjuk meg, hogy a szabályaink úgy értendők, hogy a http://www.domainunk.hu/ címet tegye elé, onnantól meg majd mi megszabjuk jól, hogy mit akarunk (lásd: RewriteRule). Ha pl. azt szeretnénk, hogy a "/nevem" könyvtárra vonatkozó URL-eket vegye csak figyelembe a Rewrite, akkor természetesen "RewriteBase /nevem" a helyes megoldás (és a htaccess-t is ebbe a könyvtárba kell tennünk). Igazából sosem voltam a szavak embere, ráadásul ezt mindenhol elég kacifántosan fogalmazzák meg. Próbálok konyhanyelven fogalmazni, remélem nagyjából érthető. :)

5-6.) A RewriteCond direktívával feltételhez kötjük az azt követő RewriteRule szabályt. A fenti esetben például azt mondjuk, hogy az "átírási szabály" (RewriteRule) csak akkor legyen felhasználva, ha az URL nem könyvtárra (!-d) és nem is fájlra (!-f) mutat. Egyértelmű, hogy a "!" tagadást jelent, a "-d" illetve "-f" pedig directory illetve file.
 
7.) Maga az átírási szabály. Mint látjuk, szimpla reguláris kifejezéseket használunk a szabályok definiálására. A fenti regexp annyit mond, hogy a RewriteBase-től nézve bármi lehet az URI, azt az index.php fájlnak adja át a szerver a rewrite változóban.

Pl.:
www.midomainunk.hu/filmek/sorozat = www.midomainunk.hu/?rewrite=filmek/sorozat

A QSA (Query String Append) flag elmagyarázása lehet, hogy túlmegy az én képességeimen de megpróbálom egyszerűen: nagyjából azt jelenti, hogy ha van, akkor a GET szuperglobálisban létrejönnek az értékeink amelyeket nem könyvtárként adunk meg: http://www.midomainunk.hu/valami/?t=1 tehát elérhető lesz a $_GET["t"], illetve az $URIParts tömb "t" eleme is létrejön, aminek az értéke 1 lesz.

8.) A feltételes blokk lezárása.

Ezek alapján már nem nagy probléma egy olyan php fájlt készíteni, amivel feldolgozzuk az átadott értékeket. Alább egy olyan "buta" példát láthatunk, ami annyit tesz, hogy egy tömbbe bontja az átadott URI elemeit. A tömb első eleme határozza meg, hogy melyik PHP fájlt kell futtatni, a soron következő elemek pedig egyszerűen paraméterként szolgálnak a futtatott állomány végrehajtásánál.

index.php:


3.) az átadott URI-t a "/" jelek mentén szétvágjuk egy $URIParts tömbbe.

5.) Ha nincs az $URIParts tömbnek nulladik eleme, akkor üres a tömb1, tehát a www.midomainunk.hu főoldalt kérte le a kliens, nem csinálunk mást, csak

6.) beincludeoljuk az ehhez tartozó fooldal.php fájlt.

7.) Ha nem üres az $URIParts tömb, és találunk a nulladik elemének megfelelő php kiterjesztésű fájlt az oldalak könyvtárban, akkor

8.) beincludeoljuk, és rábízzuk a továbbiakat az $URIParts tömb többi elemének megfelelően.

9.) Ez a feltétel akkor teljesül, ha nem üres az $URIParts tömb, de nincs is olyan php fájlunk, ami megfelelne az első elemének. Egyszerűen átirányítjuk
a felhasználót a http://www.midomainunk.hu címre.

1: jelen esetben számmal indexelt tömbbe bontjuk az URI-t, és ez az index biztosan 0-val fog kezdődni. Ez nem mindig van így, ezért alkalmazhatjuk pl a következő feltételt is:

if (count($URIParts) === 0) {

Ahogy fentebb leírtam, az $URIParts tömb 0. eleme mondja meg, hogy melyik php fájlt kell futtatnunk, a többi pedig paraméterként funkcionál. Hogy egyértelmű legyen, csináljunk egy egyszerű főoldalt, ami kétféleképpen futhat le:
a.) http://www.midomainunk.hu vagy http://www.midomainunk.hu/fooldal
b.) http://www.midomainunk.hu/fooldal/NEV, ahol a "NEV" lehet bármilyen név, és a beírt névnek kiírja, hogy "Hello NEV"

fooldal.php:

3.) Ellenőrizzük, hogy az $URIParts tömbnek van-e második eleme (mivel nullától kezdődik az indexelés, a második elem indexe 1 lesz), ha nincs,

4.) kiírjuk, hogy "Szia, Te ki vagy?"

5.) ellenben ha létezik

6.) kiírjuk, hogy "Hello ", és mögé az $URIparts második elemét.

http://www.midomainunk.hu/fooldal/Tomi = "Hello Tomi"

Kiegészítésként a wikipedia oldalain megtalálod az URL és az URI közti különbséget :)

Első nekifutásra ennyi, jó étvágyat.

3 megjegyzés:

  1. Tipp: RewriteBase csak es kizarolag akkor kell, ha az != /, ugyanis a Rewrite modul alapertelmezese az, hogy vagyunk olyan gyokerek, hogy a gyokertol induljunk.

    VálaszTörlés
    Válaszok
    1. Jobbnak láttam nem bonyolítani a RewriteBase részt. Egyszerűbb, ha ott van, és akkor nincs félreértés :)

      Törlés
    2. Vagyunk olyan Gyökerek hogy a Localhost-tól induljunk. :) :) Ez TEtszik! :)

      Törlés