Képek és htaccess
Szerző: admin | PHP | 2010 augusztus 24. 00:15

url rewrite

Megmutatom hogyan oldható meg .htaccess segítségével, hogy a http://67developer.hu/kepek/quick/thx.jpg kép a http://67developer.hu/thx.jpg címen is elérhető legyen, valamint hogyan lehet a http://localhost/67developer/ helyett http://67developer/ formában elérni az oldalt localhoston fejlesztés közben.

Kezdjük a végeredménnyel

Amit meg fogunk csinálni, és a végén le is tudtok tölteni az a következő linkeken tekinthető meg:

Ok, de ebben mi a jó? Az, hogy a thx.jpg a http://67developer.hu/kepek/quick/thx.jpg helyen van, a media67 pedig igazából http://67developer.hu/kepek/media/. Így rövidebb linkeket tudok adni úgy, hogy a fájljaimat rendezetten tartom.

Mindez az appache mod_rewrite utasításának köszönhető, amit a .htaccess fájlban használunk. De kezdjük az elején.

.htaccess

Felesleges lenne kétszer ugyanazt a tartalmat leírni, ráadásul magyar oldalról nem másolok ki tartalmat /külföldiről is csak akkor fordítok ha engedélyt adnak rá/, ezért javaslom a következő két cikk elolvasását, nagyon hasznosak:

Ha ezek megvannak, akkor minek az én cikkem? Mert szerintem gyakorlati példán mégjobban meg lehet érteni a dolgokat, és én nemigazán látok magyar oldalakon letölthető kész forráskódokat.

A kód futtatása

Eddig még nem volt róla szó, hogyan tudjátok futtatni a kódokat amiket feltöltök, de a többségnek szerintem evidens, hogy mit kell hozzá csinálni. Most mégis leírom, és pluszban mutatok egy trükköt, amivel elhagyható a localhost az urlből.

A zip fájl tartalmaz egy htaccess mappát, ezt ugye be kell másolnotok a www mappába, hogy aztán a http://localhost/htaccess/ útvonalon futtatni tudjátok. El akarjuk hagyni a localhost részt a címből, hogy csak http://htaccess/ maradjon, de vajon miért?

Az ok a következő: amikor egy elérési útvonal így néz ki hogy href=”kepek/67.jpg”, akkor ezt mindig a az aktuális url utolsó / jele után teszi. Tehát ha most a http://localhost/htaccess/kepek/index.php -ben vagyunk, és ott ezt a linket kiiratjuk, akkor az a http://localhost/htaccess/kepek/kepek/67.jpg címre vinne minket.

Mi nem ezt akarjuk, hanem hogy mindig a gyökér könyvtártól nézze a mappát. Egyszerűen megoldható, mindössze egy / kell tenni a cím elé így: href=”/kepek/67.jpg”. Most tudja a rendszer, hogy vissza kell mennie a böngésző címsorában lévő cím gyökeréig, és ahhoz kell hozzáfűzni. De hoppá! Mi történt?

Ha ezt használjuk akkor a link a http://localhost/kepek/67.jpg címre vinne át minket. Akkor most nem jó amit csináltunk? De igen, csak az oldalt nem ezen a címen kell elérni, hanem közvetlenül localhost nélkül. Ez két lépésből áll:

Először a windowssystem32driversetchosts fájlt módosítsuk. A következő sort kell hozzáadni:

1.
127.0.0.1       htaccess

Így tudja, hogy a http://htaccess/ címet a localhostra kell irányítani. Ezután XP-n az e:programokAppServApache2.2confextrahttpd-vhosts.conf fájlhoz adjuk hozzá a következőt:

1.
2.
3.
4.
<VirtualHost *:80>
   DocumentRoot e:/www/htaccess
   ServerName htaccess
</VirtualHost>

Ebből szűri le, hogy a http://htaccess/ milyen helyre mutat. Nyilván a DocumentRoot értéke az lesz ahova ti tettétek a htaccess mappát.

Elfelejtettem mondani, hogy windows xp-t futtatok és az AppServ van feltelepítve rá. Gondolom sokan használtok mást, tesztelni nem tudok ott de pl van leírás Macre vagy Linuxra is Arra kell rágooglezni hogy appache virtualhost.

.htaccess

Kukkantsunk bele a .htaccess fájlba.

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
RewriteEngine on
 
# /kutyaim.jpg
RewriteRule ^([^/]+.jpg|[^/]+.png)$ kepek/tmp/$1 [L]
 
# /rajzok67/lo.jpg
RewriteRule ^(.*)67/([^/]+.jpg|[^/]+.png)$ kepek/index.php?dir=$1&#038;kep=$2 [L]
 
# /vicces67
RewriteRule ^(.*)67/?$ kepek/index.php?dir=$1 [L]

Először bekapcsoljuk a motort ami átírja a beérkező urleket, utána pedig a megadott szűrőfeltételeket lefuttatja, amelyiken megakad az url, azt alkalmazza.

Elég nehéz egyszerűen elmagyarázni, de megpróbálom. Vegyük az első szabályt. Két részből áll, az első a ^([^/]+.jpg|[^/]+.png)/?$ ezt bontsuk részekre.

^

Azt jelenti, hogy ami utána van azzal kell kezdődnie a címnek. A címet a http://htaccess/ per jelétől számítja. Ha azt mondom hogy ^alma akkor a címnek olyan formájúnak kell lennie hogy http://htaccess/almafa

()

a zárójel arra jó, hogy ha a benne lévő dolog illeszkedik valamire, akkor azt majd a második részben visszakaphatjuk $1 formában. Péládul az előbbinél maradva a ^(a.*) ha beirjuk hogy http://htaccess/almafa akkor a második részben $1 változóban az almafa értéket tárolja. A .* azt jelenti, hogy bármilyen karakterből bármennyit elfogad.

[^/]

[] között felsorolhatunk karaktereket amiket elfogadunk. Ha beletesszük a ^ jelet akkor pedig azokat jelenti amiket nem fogadunk el. Tehát ez a szabály azt mondja, hogy bármilyen karakter lehet kivéve / jel.

+

Az előtte lévő dolog számosságára vonatkozik. A + egy vagy több előfordulást jelent. Azaz a szabályunk elfogad bármilyen szót ami nem / jel és legalább egy karakteres.

.jpg

Mivel a . egy szabály, konkrétan az ami bármilyen karaktert elfogad, ezért egy jellel escapelnünk kell, hogy tudja hogy nem a . szabályra gondolunk, hanem magára a karakterre. Ha nem ezt tennénk akkor elfogadná pl a lo?jpg szót is.

|

Vagy az előtte vagy az utána lévő szabály ha igaz, akkor elfogadja a szót.

Ha ebben az első részben elfogadja a szót, pl a kutyaim.jpg -t akkor megy a második részre ahol átirja az urlt. Ugye mi azt írtuk be hogy http://htaccess/kutyaim.jpg azonban a szerverhez már az érkezik, hogy http://htaccess/kepek/tmp/kutyaim.jpg

Ez nem olyan átirányítás mint a 301-es vagy 307-es, mert a felhasználó a címsorban még mindig az általa beírt címet látja.

A végén látható egy [L] ami azt jelenti, hogy ha a szabály elfogadta a szót, akkor ne vizsgáljon meg több szabályt, hisz lehet hogy egy későbbire is illeszkedne a szó, és akkor megint összeomlik az univerzum.

Ami még itt érdekes, hogy a másik két szabályban miért van ott a 67 ? A válasz: így mondom meg hogy ez egy képeket tartalmazó mappa. Ha nem lenne, akkor igaz hogy a képeimet el lehetne érni a http://67developer.hu/media cím alatt, viszont a http://67developer.hu/blog címen lévő blogomról is azt hinné hogy képeket tartalmazó mappa, és átirányítaná.

vicces képek

Tehát a lényeg, a http://htaccess/vicces67 címet beírva a http://htaccess/kepek/index.php?dir=vicces kód fut le, azonban a felhasználó nem az utóbbi csúnya címet látja, hanem a szép rövidet. Ugyanilyen módszerrel lehet például felhasználóbarát linkeket gyártani. Itt egy részlet a telekikoli.hu .htaccess fájljából:

1.
2.
3.
4.
5.
6.
7.
8.
9.
#Mikulás
    RewriteRule ^2009/mikulas/?$ index.php?id=mikulas [L]
#NAPTÁR
    RewriteRule ^naptar/?$ index.php?id=naptar [L]
    RewriteRule ^naptar/([0-9]{4}-[0-9]{2}-[0-9]{2})/?$ index.php?id=naptar&#038;date=$1 [L]
#ÖTLET
    RewriteRule ^otlet/?$ index.php?id=idea [L]
#reg
    RewriteRule ^regisztracio/?$ index.php?id=reg [L]

PHP

A php-t nagyon nem részletezném, a lényeg, hogy a htaccess/kepek mappában lévő index.php és init.php az ami kezeli a bejövő kép kérést, és listázza ki a mappák képeit. Azért a rendezést még leírom, hátha jól jön valakinek:

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
function glob_rsort_modtime( $patt ) {
    if ( ( $files = @glob($patt, GLOB_BRACE) ) === false ) {
        return array( false, 'Glob error.');
    }
    if ( !count($files) ) {
        return array( 'error.jpg' => 'No files found.');
    }
    $rtn = array();
    foreach ( $files as $filename ) {
        $rtn[$filename] = filemtime($filename);
    }
    arsort($rtn);
    reset($rtn);
    return $rtn;
}

Megadunk egy könyvtárat, glob függvénnyel beolvassuk a tartalmát, majd ahelyett hogy egyből visszaadnánk, csinálunk egy új tömböt, aminek a kulcsa a kép címe, az értéke pedig a létrehozás időpontja.

Most a tömbön haszáljuk az arsort() függvényt, ami érték szerint rendezi a tömböt, és szerencsére a kulcsot is viszi az értékkel együtt. Az utána lévő reset() teljesen fölösleges, arra való, hogy a tömb belső mutatóját vissza állítsa a tömb első elemére.

Összegzés

Elképzelhető, hogy a cikk kicsit tömény és zavaros, de sajnos programozó vagyok és nem ujságíró. Ha valami nem tiszta, először próbálj magadtól utána nézni, mert abból lehet a legjobban tanulni. Ha mégis lenne kérdés, akkor írd meg kommentben nyugodta, megpróbálom megválaszolni.

Lassan kezdek kifogyni az ötletekből, írjátok meg miről írjak! 67developer@gmail.com

  • Tamas Horvath

    Szia,

    a cikked alapján lenne kérdésem ;)
    én is jelenleg a htaccess adta lehetőségeket tanulom egy webáruházra alkalmazva, azonban a “járulékos fájlok” elérése (css,js, és kép fájlok) nem jutok előre

    a cél:
    aruhaz.hu/terméknév/termekid ->>> aruhaz2.php?n=termeknev&pid=termekid

    a jelenlegi htaccess
    Options +FollowSymLinks
    RewriteEngine on
    RewriteRule ^(.+)/([0-9]+)/$ aruhaz2.php?n=$1&pid=$2 [L]

    a járulékos fájlok elhelyezkedései:
    css, js -> a gyökérben (mint az aruhaz2.php)
    termékképek -> termekek mappa

    a fenti szabály alapján a járulékos fájlok elérésébe is belekerül a /terméknév/termekid/ rész.

    hogyan kell módosítani a fenti szabályt, hogy minden megjelenjen?

    Köszönöm:T:

    • http://67developer.hu/ Gergő 67

      Szia!

      Csináltam egy rövid példát azok alapján amit írtál, elérhető a http://67developer.hu/files/blog/htaccess/67.rar címen. A lényeg, hogy ha localhoston futtatod a dolgokat, akkor nem hivatkkozhatsz az oldaladra úgy, hogy http://localhost/proba/akarmi.php, mert akkor a localhost lesz a domain, és a htaccess a feldolgozásba a proba részt is beleveszi.
      Nem tudom az áruházadat hogy tesztelted, de a cikkben leírtam, hogy a httpd-vhosts.conf és a hosts fájlba létre kell hozni egy-egy bejegyzést az oldalaknak, hogy direktbe el lehessen őket érni.
      Ha a mostani próba fájlt is így teszteled, akkor amennyiben a http://proba/ címen el tudod érni, úgy a következő linkek működnek:
      http://proba/design.css egy css fájl
      http://proba/termekek/67.png egy kép
      http://proba/akarmi/123/ asd.php?n=$1&pid=$2
      Amennyiben ez sem működne, írj a 67developer@gmail.com címre, és részletesebben átbeszéljük, a megoldást pedig itt közöljük.

  • Tamas Horvath

    Szia,

    a cikked alapján lenne kérdésem ;)
    én is jelenleg a htaccess adta lehetőségeket tanulom egy webáruházra alkalmazva, azonban a “járulékos fájlok” elérése (css,js, és kép fájlok) nem jutok előre

    a cél:
    aruhaz.hu/terméknév/termekid ->>> aruhaz2.php?n=termeknev&pid=termekid

    a jelenlegi htaccess
    Options +FollowSymLinks
    RewriteEngine on
    RewriteRule ^(.+)/([0-9]+)/$ aruhaz2.php?n=$1&pid=$2 [L]

    a járulékos fájlok elhelyezkedései:
    css, js -> a gyökérben (mint az aruhaz2.php)
    termékképek -> termekek mappa

    a fenti szabály alapján a járulékos fájlok elérésébe is belekerül a /terméknév/termekid/ rész.

    hogyan kell módosítani a fenti szabályt, hogy minden megjelenjen?

    Köszönöm:T:

  • Stonk

    szia,

    Köszi a segítséget, sokat dobott a felfogásomon a cikk, viszont egy dolognál elakadtam.

    Többszintű menüszerkezetet használok, css-el megformázva. A főbb menüpontok hivatkozása egy #.

    A probléma az, hogy amikor rákattintok, akkor kinyílik (lenyílik) a menüpont, de rögtön át is dob a nyitóoldalra. Pedig én nagyon szeretném, ha a megnyitott menüpont maradna és a menü lenyílna.

    A htaccess fileom tartalma:

    RewriteEngine on
    RewriteBase /uj_/

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

    RewriteRule ^(.*)$ /uj_/index.php?lang=$1 [L]
    RewriteRule ^(.*)/$ /uj_/index.php?lang=$1 [L]

    Egy tömbben adom át a linkeket és darabolom szét, de ez végül is lényegtelen.

    Mit kellene beírnom még a fileba, hogy ne vegye figyelembe az “üres” linkeket?

    Köszi:
    Gábor

    • http://67developer.hu/ Gergő 67

      Szia!

      Ha van mód rá, megnézném azt a kódot, mivel nem hiszem, hogy ennek a htaccess-hez lenne köze. Direkt úgy akartad, hogy kattintásra nyíljon le a menü, és ne akkor ha fölé viszed az egeret?
      Egyébként ha a hivatkozás egy sima # akkor biztos nem fog más oldalra navigálni a böngésző, viszont ha nem az oldal tetején voltál, akkor felugrik oda, talán ezt látod annak hogy újratöltődik. Vannak jó javascriptes megoldások kattintósra, de css-ben az egeretföléhúzós is megoldható.
      Ha rosszul gondolom, akkor 67developer@gmail.com-on írj rám és megpróbáljuk megoldani. Ha jól tippeltem, akkor is írhatsz, aztán keresünk valami legördülő menüt ami megfelel neked.

      Gergő

  • Stonk

    szia,

    Köszi a segítséget, sokat dobott a felfogásomon a cikk, viszont egy dolognál elakadtam.

    Többszintű

      menüszerkezetet használok, css-el megformázva. A főbb menüpontok hivatkozása egy #.

      A probléma az, hogy amikor rákattintok, akkor kinyílik (lenyílik) a menüpont, de rögtön át is dob a nyitóoldalra. Pedig én nagyon szeretném, ha a megnyitott menüpont maradna és a menü lenyílna.

      A htaccess fileom tartalma:


      RewriteEngine on
      RewriteBase /uj_/

      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d

      RewriteRule ^(.*)$ /uj_/index.php?lang=$1 [L]
      RewriteRule ^(.*)/$ /uj_/index.php?lang=$1 [L]

      Egy tömbben adom át a linkeket és darabolom szét, de ez végül is lényegtelen.

      Mit kellene beírnom még a fileba, hogy ne vegye figyelembe az “üres” linkeket?

      Köszi:
      Gábor

    • http://67developer.hu/ Gergő 67

      Szia!

      Ha van mód rá, megnézném azt a kódot, mivel nem hiszem, hogy ennek a htaccess-hez lenne köze. Direkt úgy akartad, hogy kattintásra nyíljon le a menü, és ne akkor ha fölé viszed az egeret?
      Egyébként ha a hivatkozás egy sima # akkor biztos nem fog más oldalra navigálni a böngésző, viszont ha nem az oldal tetején voltál, akkor felugrik oda, talán ezt látod annak hogy újratöltődik. Vannak jó javascriptes megoldások kattintósra, de css-ben az egeretföléhúzós is megoldható.
      Ha rosszul gondolom, akkor 67developer@gmail.com-on írj rám és megpróbáljuk megoldani. Ha jól tippeltem, akkor is írhatsz, aztán keresünk valami legördülő menüt ami megfelel neked.

      Gergő

  • http://67developer.hu/ Gergő 67

    Szia!

    Csináltam egy rövid példát azok alapján amit írtál, elérhető a http://67developer.hu/files/blog/htaccess/67.rar címen. A lényeg, hogy ha localhoston futtatod a dolgokat, akkor nem hivatkkozhatsz az oldaladra úgy, hogy http://localhost/proba/akarmi.php, mert akkor a localhost lesz a domain, és a htaccess a feldolgozásba a proba részt is beleveszi.
    Nem tudom az áruházadat hogy tesztelted, de a cikkben leírtam, hogy a httpd-vhosts.conf és a hosts fájlba létre kell hozni egy-egy bejegyzést az oldalaknak, hogy direktbe el lehessen őket érni.
    Ha a mostani próba fájlt is így teszteled, akkor amennyiben a http://proba/ címen el tudod érni, úgy a következő linkek működnek:
    http://proba/design.css egy css fájl
    http://proba/termekek/67.png egy kép
    http://proba/akarmi/123/ asd.php?n=$1&pid=$2
    Amennyiben ez sem működne, írj a 67developer@gmail.com címre, és részletesebben átbeszéljük, a megoldást pedig itt közöljük.