ugrás a tartalomhoz

mod_rewrite: üres mappák, 404-es hibaüzenetek és hivatkozások

jeti · 2007. Már. 24. (Szo), 14.26
Sziasztok!

Most kezdtem el foglalkozni a rewrite modullal, és újabb hibákba ütköztem, amire már nem találtam megoldást. A segítségeteket szeretném kérni. A helyzet a következő: Van egy www mappám, abban egy .htacces, egy hiba404.php és az index.php. (Ami jelenleg fontos.) Továbbá vannak almappáim: chat, cikk, link, forum stb. Ezekben csupán egy .htacces fájl van.
A http://localhost/teszt/www/ címre bejön a honlap.
Ha beírom pl. azt a címet, hogy http://localhost/teszt/www/forum/tema/16, az is rendben van. (Az index.php-ban megkapom azt, hogy $m=forum és $e=tema/16.)
1.) Üres mappa
Ha csak azt írom be hogy http://localhost/teszt/www/forum, akkor megjelenik az „Index of /teszt/www/forum” lista üresen a Parent Directory linkkel. Amikor én azt szeretem volna, hogy írja át az index.php$m=forum címre.
Az almappa .htacces fájla:

ErrorDocument 404 http://localhost/teszt/www/hiba404.php
<IfModule mod_rewrite.c>
 RewriteEngine On

  # Minden nemletezo oldal webcimet iranyitsuk at az index.php-re
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^(.*)$ ../index.php?m=forum&e=$1 [QSA]

</IfModule> 
Minden mappában ugyanez csak az $m a mappa neve. Tudom, hogy meg lehetne oldani csak egy .htacces fájlal a www mappán belül, de ezek a mappák lesznek az aldomainek célpontjai. Sajnos, a tárhely szolgáltató nem engedélyezi az egyedi aldomain név kezelést, ezért kell így trükköznöm. Ha tudsz egyszerűbb megoldást, akkor légy szíves oszd meg velem.



2.) 404-es hibaüzenet
Az index.php így kezdődik:

<?php
if ($e=="hello") {header("HTTP/1.0 404 Not Found");}
# ...
?>
A www mappa .htacces fájla így néz ki:

ErrorDocument 404 http://localhost/teszt/www/hiba404.php
<IfModule mod_rewrite.c>
 RewriteEngine On

  # Minden nemletezo oldal webcimet iranyitsuk at az index.php-re
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^(.*)$ teszt/www/index.php?e=$1 [QSA]
</IfModule>
Ha megadom ezt a címet, hogy http://localhost/teszt/www/forum/hello, akkor ugyanúgy bejön az oldal, mintha jó lenne a cím.

3.) Hivatkozások
Az összes hivatkozás (kép, stíluslap) elromlik, megváltozik több mappa mélységben. Használjak abszolút hivatkozásokat, vagy van valamilyen csel, amivel megmaradhatnak a relatív hivatkozások is?

Előre is köszönöm mindenkinek a segítségét.
 
1

Egyszerübben

vbence · 2007. Már. 24. (Szo), 15.52
A hivatkozásokhoz használj <base href="..." /> -t. A htaccess fájlokat nincs értelme errordocumentel és rewrite-tal is megírni. Így csökkenni fog a rendszer bonyolultsága (kevesebb hibalehetőség).

Az index.php szétbonthatná az egész URL-t regex-szel. Semmi értelme a htaccessben paraméterekkel bajlódni. A PHP úgyis megkapja az eredeti URL-t.

Ha aszolgáltató az aldomaineket könyvtárneveknek mappeli be attól még símán lehet egy htaccess fájl. Az index php-ben ezt is fel tudod dolgozni.

A teszt/www/ előtagot nem igazán értem a címeknél... Tényleg nem.

Ne tervezd az oldalt aldomainekre szétbontva, hacsak nincs rá nyomós okod (pl már most tudod, hogy külön szerverekre fog kerülni). Nem sikk, nem menő, nem jó az egészségednek.
2

404: hogy működik?

jeti · 2007. Már. 24. (Szo), 18.46
Köszönöm. A <base href="..." />-val megoldódott a 3. problémám. Nem tudom, hogy miért nem jutott eszembe... :-)

Az első kettő már nehezebb eset.
„A htaccess fájlokat nincs értelme errordocumentel és rewrite-tal is megírni.”
Nekem mindegy, hogy mivel írom meg, csak ha kiadom a 404-s hibaüzenetet, akkor ne töltsön be változatlanul az oldal! Hanem a hiba404.php fájlt jelenítse meg. (Ez lehetne html is, mivel jelenleg csak ez van benne. „<P id=”404”>404: Hiba ez az oldal nem található!</P>”)
Tehát alapjába véve rewrite modult szeretném használni, csak 404-s http fejléc kiadásakor az adott fájlt (hiba404.php) töltse be, mert most bármilyen címre betölti az oldalt... Nem tudom, hogy érthető-e a problémám.
Pl.: Ha azt írom be, hogy forum/tema/disznóparéj, akkor az rossz cím, mert én csak számot várok. Most betölti az oldalt hibaüzenettel, amikor azt szeretném, hogy csak a 404-es hibaüzenetet töltse be.
Vagy független a http fejléc az alatta lévő tartalomtól?
Mit jelent az, hogy egyedi 404-es hiba oldal beállítása? Nem azt, hogy ha a http fejlec 404-et kap akkor az eredeti kéréstől függetlenül egy előre megadott lapot tölt be?

Tulajdonképpen csak barátságos hibaüzenetet akarok készíteni. Mint ahogy a weblaboros cikk is írja.
http://weblabor.hu/cikkek/baratsagos404
3

üres mappák

jeti · 2007. Már. 24. (Szo), 19.13
Nekem is sokkal egyszerűbb, ha csak egy .htaccess fájlom van, de úgy sehogy sem működik az átirányítás.
Kipróbáltam több féle variációt. A www mappában mindig ott van a korábban említett fájl. A lekérés címe: http://localhost/teszt/www/forum

1.) forum mappában van egy index.php header("location: index.php?m=forum");
- átugrik a címre, és látszik a php-s cím
2.) forum mappában van egy .htaccess fájl
- félig meddig működik (Ha van a lekérésben egy újabb almappa (http://localhost/teszt/www/forum/tema), akkor rendben. Különben (http://localhost/teszt/www/forum) listázza a mappa tartalmát.)
3.) teljesen üres a forum mappa
- listázza a mappa tartalmát
4.) nincs, nem létezik a forum mappa
500: „Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator, [no address given] and inform them of the time the error occurred, and anything you might have done that may have caused the error.

More information about this error may be available in the server error log.

Apache/1.3.31 Server at localhost Port 80”

Mindegy, hogy adom át a címet, egy darabban, vagy többen, csak kapja meg az index.php. Onnantól kezdve már bármit tudok vele csinálni, csak így hogy el se jut odáig, meg vagyok lőve!

Ui.: A http://localhost/teszt/www/forum/ csak az otthoni cím, elvileg forum.domainem.hu lesz, de elérhető lesz domainem.hu/forum cím alatt is.

Remélem ezzel a megoldással a forum.domainem.hu/tema/5 és a domainem.hu/forum/tema/5 is eljut az index.php-hoz.
4

Válasz

vbence · 2007. Már. 24. (Szo), 21.40
Először az első hozzászólásra:
Az apache belső feldolgozása sajnos nem úgy működik, ahogy gondolod. Az ErrorDocument 404 ... és az alatta lévő rewrite szabály egyenértékű. (Szerintem a rewrite lesz nagyobb prioritású, úgyhogy a másik nem vátoztat semmit.) A lényeg: mindkettő a valódi kérés végehajtása ELŐTT értékelődik ki. Az nem működik, hogy a PHP visszküldi a 404-et és arra az apache reagál. (Ez egy reverse-proxy szerű viselkedés lenne.)
Ha hibát akarsz visszaadni, egyszerűen include-old be az index.php-ből a hiba404.html-t ha nem tudod értelmezni az URL-t.

A rewritehoz:
Ahhoz, hogy működjön mindössze ennyire van szükséged (a site gyökérben egy .htaccess):

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* handler.php [QSA]
Azért nem index.php, mert így kevesebb az esély, hogy összekeveredsz a directory-indexszel. A handler.php -ben futtass egy phpinfo()-t és máris meglátod hol lesz az eredeti URL (talán $_SERVER["REDIRECT_URL"] vagy hasonló, de lehet, hogy a $_SERVER["REQUEST_URI"] is arra mutat - mindenféle beállításoktól függ).

A tesztszerveren tedd agyökérbe az oldalt, mindek szivatod magad fölöslegesen, ha az éles környezetben is úgy lesz...

Az aldomain (ismételten megjezem) nem jó ötlet. Az oldaladon biztos lesz egy nagy fejléc-kép. Ezt hogy linkeled be a HTML-ben, hogy a forum.domainem.hu/tema/5 és a domainem.hu/forum/tema/5 címről is működjön? (Teljes url-t adsz meg, és a statikus elemek másik domaonről jönnek majd, ha valaki a subdomainen nézi az oldalt?)
5

már tisztul

jeti · 2007. Már. 25. (V), 10.48
Köszönöm. Jó, már értem a hibaüzeneteket is.

global $REDIRECT_URL;
if ($REDIRECT_URL=="nincs_ilyen_oldal_(teszt)") {header("HTTP/1.0 404 Not Found"); include(’hiba404.php’); exit;}
Tehát csak ennyi a teendőm, és a keresők nem indexelik, és a böngészők látják, hogy ez nem a keresett tartalom, csak egy 404-es üzenet. Ez is kipipálva. :-)

Illetve mégse? Még egyszer leellenőriztem, ha az exit();-et lecserélem phpinfo();-ra, akkor azt írja (a php fájl), hogy REDIRECT_STATUS: 200. Ha a Firefox Live HTTP hedaers-el vizsgálom a történéseket, akkor először azt kapom, hogy HTTP/1.x 404 Not Found. Ha az exit();-et lecserélem, akkor a következő adagban már ezt: HTTP/1.x 200 OK. Akkor most mi van? :-(

Az elsőnél is javult a helyzet.
A nem létező mappáknál már nem kapok 300-as hibát, és hozzáférek a címekhez is a $REDIRECT_URL-al.
De az üres mappáknál továbbra is csak a mappa listázása fogad. Próbálkoztam a
RewriteCond %{REQUEST_FILENAME} !-d 
sor törlésével, de még így se jó. :-(

Sajnos, az aldomaineket nem tudom kipróbálni. Nem lehetne valahogy szimulálni? A jelenlegi szolgáltatomnál nem használhatok a .htacces fájlok, és az újat akkor szeretném megrendelni, ha már működik a honlap.
Ilyenkor milyen címet kapok? Azt a címet kapom meg, amit beírtak, vagy az aldomain a domainem.hu mögé lesz illesztve?
Korábbi példánál maradva...
1.) REDIRECT_URL: forum.domainem.hu/tema/5
2.) REDIRECT_URL: domainem.hu/forum/tema/5
Melyiket kapja meg a handler.php-m?
Számomra az lenne a jó, ha csak az 1.)-est, hogy mindig tudjam, hogy melyik az aldomain.

A forum.domainem.hu nem volt a legjobb példa, de van okom a szétbontásra, mivel néhány felhasználható hozhat létre saját aldomaint. Ekkor az összes program az ő aldomainük alatt is meg lesz jelenítve.
Csak a forum.domainem.hu lesz, és a többi programoknál, mint blog, link, cikk stb. is csak egy kezdőlap lesz. Ellenben a többivel, ami mögé illesztem a pontos modul címét.
Pl.:
mazsola.domainem.hu/forum/tema/2
mazsola.domainem.hu/cikk/5
fuge.domainem.hu/forum/tema/3
fuge.domainem.hu/cikk/7
fuge.domainem.hu/blog/9
gumikacsa.domainem.hu/forum/tema/1
gumikacsa.domainem.hu/recept/8

Az nem von le semmit az oldal értékéből, hogy csak php-ban értelmezem a URL címeket?
6

pontosabban

vbence · 2007. Már. 25. (V), 11.59
A phpinfó elrontja a 404-et? Próbáld ki ezt:
<?
	header ("HTTP/1.0 404 Not Found");
	phpinfo ();
?>
Amúgy meg kitérdekel :) Úgyse infót fosz küldeni a 404-es lapban...

Miért kell az üres mappa? Töröld le.

Egy normális teszkörnyezetet könnyen össze tudsz állítani magadnak. Hozz létre egy név alapú virtualhostot (NameVirtualHost *) a httpd.conf -ban. Majd egy olyan virtualhostot, ahol ServerName domainem.test és ServerAlias *.domainem.test - ezután a windows/system32/drivers/etc/hosts (ha jól emlékszem) fájlban (lehet, hogy létre kell hozni, lesz egy hosts.sam mintafájl is) adjál meg néhány próba hostot:

domainem.test 127.0.0.1
forum.domainem.test 127.0.0.1
fuge.domainem.test 127.0.0.1
gumikacsa.domainem.test 127.0.0.1
Apache restart, majd nyomsz (parancssorban) egy ping domainem.test -et (csak hogy tudatosuljon benne az új beállítás), ezután ha benyomkodod kedvenc böngésződbe a domainem.test cím alatt bejön a szervered (A virtualhostban adjál meg neki saját DocumentRoot -ot, így több független projektet tudsz csinálni a tesztszerveren).

Az aldomainekre gondold meg azt, hogy csak egy redirect oldal lesz a *.domainem.hu, ami azonnal 301-et küld a domanem.hu/* -ra. Így az ügyfélnek megmarad a saját hostnév érzése (felírhatja a névjegykártyára stb..) és te sem szívsz vele annyit.

Hát remélem, hogy nem von le az oldal értékéből.. én már egy ideje ezt használom :) De kredibilisebb forrásból is ajánlhatom:
http://weblabor.hu/cikkek/rovidwebcim
7

2 független cím és cookie-k

jeti · 2007. Már. 26. (H), 21.59
Újra köszönöm a segítségedet. :-) Több probléma után végül sikeresen beállítottam a domainem.test címet, az aldomainek is rendben vannak. Ám egy újabb problémába ütköztem: a domainem.test és a localhost címen is ugyanaz jön be. Egészen pontosan a domainem.test mappája. Ez miért van? Hogy lehetne ezt beállítani? Természetesen a két útvonal nem ugyan az...

Jó, a 404-est úgyse így fogom használni... :-) Csak már aggódtam, hogy én rontottam el valamit, nem a phpinfo();.
Az üres mappa nekem nem kell, csak azt hittem, hogy az aldomainokat csak külön mappára lehet irányítani. Letörlöm...
Ezzel kapcsolatban még annyi, hogy van néhány mappa, ami nem üres. Pl.: a kepek, akkor ide be kell tennem egy újabb .htacces-t.

Az aldomaineket nem akarom ilyen módon átirányítani, de jó ötlet. Persze, rá tudnám erőltetni, csak így számos előnytől elesnék. Nagyon sokat gondolkoztam ezen, valószínűleg az lesz, hogy az aldomainek csak egy speciális főoldalra mutatnak. Tehát nem halmozok fel utánuk mappákat (pl.: fuge.domainem.hu/forum/tema/214).
Hogy lehet a cookie kezelést és a munkamenet azonosítót kiterjeszteni az egész webhelyre?
8

subdomain és cookie

vbence · 2007. Már. 27. (K), 01.48
Azok a címek nem annyira függetlenek (szerencsére). A felsőbb szintű domainen beállított cookie-t látják az aldomainek is. Tehát ha a domainem.hu/login.php (www nélkül!) nyom egy session cookie-t, azt (elvileg) látnia kell a forum.domainem.hu-nak is.

A login.php-t megírhatod úgy, hogy a Referer-re ugorjon egy 302-val, miután megtatte a dolgát. Így az aldomaineken található formot ráirányíthatod, az login után a hívó aldomainre tér vissza.

A php dokumentáció azt ajánlja, hogy kompatibilitási okokból a setcookie ()-nak .doainem.hu domain paramétert adj meg ilyenkor.

A NameVirtualHost * az összes interfészre bekapcsolta a virtuális hostolást. Ilyenkor ez felülírja az alap hostot. A default host a legelső virtualhost lesz. Ha olyan hostnevet adsz meg, amihez tartotik külön virtualhost beállítás, a defaultot fogja használni. Ez történik akkor is, ha pl annyit írsz be, hogy 127.0.0.1
A megoldás: vegyél fel a mostani elé még egy virtuálhostot, ebbe írd a default beállításokat. A jobb megoldás: az otthoni tesztszerveren semmi értelme a defaultot használni. Ha más projekthez is hazsnálod a szervert, vegyél fel projektenként virtuaéhostokat.
9

IfModule mod_rewrite.c

Dualon · 2007. Már. 27. (K), 08.56
Csak a pontosság kedvéért:

<IfModule mod_rewrite.c>
RewriteEngine on
...
</IfModule>
Enélkül tévedésből, nem engedélyezett RewriteEngine mellett el lehet hasaltatni a szervert.
10

httpd.conf

vbence · 2007. Már. 27. (K), 12.21
... mármint akkor, ha a httpd.con-ban van. Ha .htaccess-ben, akkor nem ekkora a baj, csak az oldal nem működne. De így legalább lehet egy index.html-t csinálni, hogy "Nem üzemelünk" az "Internal Error" helyett.
11

Árt? :)

Dualon · 2007. Már. 27. (K), 12.38
Szemlélet kérdése, szvsz elegánsabb figyelni rá.
12

Neeeeem

vbence · 2007. Már. 27. (K), 13.15
Egyetértek "Csak a pontosság kedvéért" írtam ;)
13

:)

Dualon · 2007. Már. 27. (K), 13.16
Jogos! :)
14

Köszönet

jeti · 2007. Már. 27. (K), 19.20
Köszönöm szépen a segítségedet. Úgy látszik mindent problémát sikerült megoldanunk.
Ezt már csak elegáns megoldás miatt kérdezem, hogy lehet egyedi 500-as hiba üzenetet beállítani?

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* handler.php [QSA]
</IfModule>
RewriteRule .* 500_nemuzemelunk.php [QSA]
Ilyenkor 500-as fejlécet ad, vagy nekem küldenem egy 302-es fejlécet (Moved Temporarily)?
15

500

vbence · 2007. Már. 27. (K), 20.22
Ha 500, azaz belső hiba van, az tipikusan az elírt htaccess miatt lehet. Ilyenkor ugyebár tökmindegy, hogy felül próbálod írni, ha azt a hibás htaccessben teszed. A VirtualHost-ban megahatsz egy ErrorDocument-et.

Mellesleg a fenti rewrite ha belegondolsz több szempontból is értelmetlen.

Éles környezetben ritkán keletkezik 500. Főleg, ha PHP-t használsz, úgyhogy csak ez inkább cicoma...