Zaawansowane szukanie | Nowości
Newsy | Artykuły | Programowanie: Pascal, Object/Delphi Pascal, C++, PHP, Javascript | Poradniki | Recenzje | FAQ | Mapa

Artykuł: PHP - Mod_Rewrite zastosowania praktyczne

Tytuły podstron w linkach


W poprzednim artykule napisałem jak budować schematy przepisywania linków. Były to proste przykłady. Teraz mam zamiar pokazać, jak stworzyć linki typu http://www.nazwadomeny.pl/Artykuły/Nazwa artykułu. Nie jest to rzecz trudna, jeżeli nasz system używany na stronie potrafi odczytać artykuł po nazwie nie używając ID. W takim przypadku tworzymy jedynie wpis:
RewriteRule ^([^-]+)/(.*)$ index.php?modul=$1&nazwa=$2 [L,NC,NS]
Z powyższego przykładu można wywnioskować, że znaki (.*) pozwalają na podanie dowolnej wartości. Klikając w link Artykuły/Nazwa artykułu wczyta nam się strona index.php?modul=Artykuły&nazwa=Nazwa artykułu. Wtedy na naszej stronie kod wczytujący artykuł powinien odwołać się najpierw do nazwy, a później do ID. Jeśli nie mamy takiej możliwości lub wiedzy, możemy stworzyć funkcję GetIDFromName(), która wczyta z nazwy artykułu ID, a potem samo ID zostanie załadowane. Przykładem byłoby GetIDFromName($nazwa);. Ten artykuł nie ma jednak na celu opisywania dokładniej tych procedur. Jest jeszcze jeden problem - nie wszystkie przeglądarki wczytują adresy z polskimi znakami czy spacjami, a także nie każde kodowanie poprawnie wyświetla taki link. Aby nie mieć problemów najlepiej jest zmienić nazwę artykułu np. z "Chrząszcz lata po łące, a Ala ma kota!" na "chrzaszcz_lata_po_lace,_a_ala_ma_kota". O tym w rozdziale:

Zamiana zdań w linkach


Jak już mówiłem wyżej, lepiej nie kombinować i zrobić sobie urle, gdzie wszystkie litery będą bez polskich znaków, a spacje zastępować będzie znak "_". Dodatkowo zróbmy tak, aby wszystkie inne znaki specialne zmieniały się na myślnik. Posłuży nam do tego funkcja:
function zamieniaj($text)
{
	$text = html_entity_decode($text);
	$szukaj = array(
		' ',
		'/',
		'\'',
		'&',
		'%',
		'ć',
		'ś',
		'ą',
		'ż',
		'ó',
		'ł',
		'ś',
		'ż',
		'ń',
		'ę',
	);
	$zamieniaj = array(
		'_',
		'-',
		'-',
		'and',
		'procent',
		'c',
		's',
		'a',
		'z',
		'o',
		'l',
		's',
		'z',
		'n',
		'e',
	);
	$text = strtolower($text); // Zamiana na małe litery
	$text = str_replace($szukaj, $zamieniaj, $text); // Zamiana znaków z tablic
	return $text;
}
?>
Jak widać funkcja ta powoduje zamianę polskich znaków na litery bez "ogonków", a dodatkowo zmienia wszystkie litery na małe, znaki specialne na słowa, a spacje na "_". Zastosowanie takiej funkcji jest proste - wystarczy w pliku danego systemu portalowego odpowiedzialnego za wyświetlanie newsów, dodać funkcję do linku prowadzącego do danego artykułu. Załóżmy, że w pliku news.php znajduje się szablon do newsa, a zmienna $title odpowiada za tytuł. Zmienna ta oczywiście domyślnie nie jest zamieszczona w linku, bo systemy wczytują artykuły według ID. Znajdźmy zatem fragment składnią podobny do tego:
<a href="index.php?modul=artykuly&id='.$id.'">'.$title.'</a>
Aby od razu zmienić nasz link na krótki url, zamieńmy powyższy fragment na:
<a href="Artykuly/'.zamieniaj($title).'">'.$title.'</a>
Dzięki czemu zamieniony, dzięki funkcji "zamieniaj", zostanie jedynie tytuł w linku. Co jednak jeśli musimy podać ID? Modyfikujemy odpowiednio regułę w .htaccesss i zmieniamy kod na:
<a href="Artykuly/'.$id.'/'.zamieniaj($title).'">'.$title.'</a>
Co spowoduje, że link będzie wyglądał tak: Artykuly/1/nazwa_artykulu.

Zastosowanie w systemach CMS


Poprzedni rozdział przeznaczony jest dla osób, które wiedzą gdzie i jakie pliki się znajdują oraz jak je zmodyfikować - czyli głównie dla tych, którzy korzystają z własnych rozwiązań. Napiszę teraz jak poradzić sobie z krótkimi linkami w systemach portalowych. Podam przykład na CMSach PostNuke, MdPro oraz PHP-Nuke (dla większości systemów opartych na "Nuke", jak np. enVolution, też powinno to zadziałać). Te CMSy mają plik odpowiedzialny za tytuły i linki zawarty w katalogu modules/News/. Jego nazwa to funcs.php. Otwieramy go, po czym dodajemy funkcję "zamieniaj" zaraz po komentarzu autora, następnie odszukujemy komentarz "// Allowed to read full article?" i wstawiamy pod nim:
$zamiana = zamieniaj($info[title]);
Zmienna $zamiana będzie teraz wywoływała funkcję "zamieniaj" na zmiennej $info[title], która jest odpowiedzialna za wyświetlanie tytułu. Poniżej widzimy:
if (pnSecAuthAction(0, $component, $instance, ACCESS_READ)) {
a pod tym definicję zmiennej $fullarticle. Zamieniamy całą poniższą linijkę na:
$fullarticle = "$zamiana-id$info[sid].html";
Teraz nasze nazwy artykułów będą wyglądały np. tak: "chrzaszcz_brzmi_w_czcinie,_a_ala_ma_kota-id1.html".
Zacząłem może trochę od tyłu. Te systemy CMS wspierają krótkie linki, jeżeli zainstalujemy moduł do generowania layoutu o nazwie AutoTheme. Są też inne moduły, które dają taką możliwość, ale AutoTheme jest standardowym modułem w PHP-Nuke i MdPro, a do PostNuke należy go zainstalować. Moduł jest bardzo popularny, dlatego lepiej z niego korzystać. Po aktywacji AutoTheme (wszystkie problemy rozwiązą strony z supportami) kopiujemy plik html.htaccess, htm.htaccess lub phtml.htaccess (wybieramy jaki chcemy mieć surfix) do głównego katalogu strony i zmieniamy nazwę na .htaccess. Później w panelu administracyjnym AutoTheme wchodzimy w Dodatki i ustawiamy opcję "ShortUrls" na TAK, po czym klikamy obok na link "Konfiguruj" i zmieniamy surfix na wybrany przez nas w pliku. AutoTheme domyślnie wspiera surfixy, nie ma jednak możliwości zmiany na brak surfixu (przynajmniej domyślnie). Po tych operacjach mamy już włączone przyjazne linki i jak widać automatycznie zostały zmienione na stronie. Można sobie zadać pytanie - jak to się stało? Otóż AutoTheme używa funkcji preg_replace do dynamicznej zamiany linków na krótkie. Tą funkcję właśnie pragnę przedstawić, aby każdy, kto ma forum lub jakiś większy skrypt, nie musiał ręcznie zmieniać linków, bo w końcu można posłużyć się funkcją, która zrobi to za nas. Otwieramy zatem plik modules/AutoTheme/extras/[nazwa_systemu]/autourls.ext.php (gdzie [nazwa_systemu] to postnuke, mdpro lub phpnuke). Widzimy funkcję preg_replace z podaną tablicą (array), dzięki czemu funkcja będzie działać szybciej (inaczej preg_replace będzie spowalniać ładowanie strony). Następnym krokiem dla użytkowników będzie edycja wpisów w tablicy "search" i "replace", pierwsza odpowiada za to jakie linki system ma wyszukać, a druga - na jakie zamienić. Przykładowo:
Wpis w tablicy Search:
$prefix . 'index.php\?newlang=([\w\d\.\:\_\/]+)"|',
Zamienia na wpis w tablicy Replace:
'"changelang-$1.'.$autourlsext.'"',
Gdzie zmienna $autourlsext oznacza surfix. Oczywiście każda pozycja w tablicy "search" odpowiada tej samej pozycji w tablicy "replace", tzn. funkcja zamienia te same linijki tablicy "search" na te same w "replace". Trochę teorii: jeżeli chcemy dodać własną pozycję i zamieścić np. index.php?module=coś&file=coś musimy pamiętać, że znak & należy zapisać: &(?:amp;)? i każdy wpis należy zakończyć "|. Według tego nasz przykładowy link powinien być zapisany tak:
'index.php\?module=coś&(?:amp;)?file=coś"|'
Pamiętajmy także o tym, że każdą pozycję lepiej zacząć zmienną $prefix, a kończyć przecinkiem. Na koniec należy jeszcze odpowiednio zmodyfikować reguły w pliku .htaccess tak, aby były one zgodne z plikiem autourls.ext.php. Myślę, że po przeczytaniu mojego poprzedniego artykułu o mod_rewrite, nie powinno być z tym problemów.
Na koniec chciałbym jeszcze napisać jak użyć preg_replace w przypadku forum czy jakiegoś większego skryptu (może to być nawet CMS, który nie wspiera przyjaznych linków). Stwórzmy funkcję Rewrite() i dodajmy do niej tablice "search" oraz "replace":
function Rewrite($display) {
	$search = array( 
		'index.php\?pokaztemat=([\w\d\.\:\_\/]+)&(?:amp;)?file=([\w\d\.\:\_\/]+)"|',
		'index.php\?pokazpost=([\w\d\.\:\_\/]+)&(?:amp;)?file=([\w\d\.\:\_\/]+)"|',
		'index.php\?pokazkategorie=([\w\d\.\:\_\/]+)&(?:amp;)?file=([\w\d\.\:\_\/]+)"|'
	);
	$replace = array( 
		'"pokaztemat-$1-file-$2"',
		'"pokazpost-$1-file-$2"',
		'"pokazkategorie-$1-file-$2"'
	);
	
	$display = preg_replace($search, $replace, $display);
	
	return $display;
}
Jest to oczywiście przykład. Wiadomo, że każdy ma inne urle, dlatego też trzeba samemu przystosować sobie taką funkcję. W tablicy "search" w miejscu, gdzie definiujemy daną zmienną, należy wstawić znaki ([\w\d\.\:\_\/]+). Ostatnia pozycja w tablicy nie może być już zakońcona przecinkiem. W tablicy "replace" pola na zmienne ustawiamy tak jak w pliku .htaccesss, czyli pierwsza zmienna to $1, druga $2 itd. Powyższa funkcja zamienia np. link index.php?pokaztemat=3&file=index na pokaztemat-3-file-index.

Zapraszam więc do modyfikacji. Jeszcze taka krótka notatka ode mnie - wszystko zawarte w poradniku o mod_rewrite jest napisane na bazie mojego doświadczenia. Piszę to dlatego, że ktoś może pomyśleć, iż napisałem poradnik na bazie np. artykułu z polskiego supportu MdPro o przerabianiu przyjaznych linków. W każdym razie na jedno by wyszło, bo to ja jestem autorem poradników o przerabianiu przyjaznych linków w AutoTheme, które znajdują się na polskich supporach CMSów.
Dodano: 20 marca 2006, Wróć do "Mod_Rewrite"
Autor: Michał Gacki
Główny programista i założyciel Bil Software.
Informacje o autorze | Kontakt