Vytvoření přátelského URL

Především kvůli vyhledávačům, ale zčásti i kvůli uživatelům je populární používat přátelská URL. Místo clanek.php?id=12 se tedy používá např. kde-nas-najdete/. Přepis URL může zajišťovat např. mod_rewrite, vytváření správných URL je vhodné nechat na zkušeném uživateli, často se ale generují jednoduše z nadpisu – nejsou pak sice tak úderné, jak by mohly být, ale zase s tím je nejméně práce.

Přestože URL může obsahovat znaky s diakritikou (což používá např. Wikipedia), bývá zvykem ji odstranit a v URL nechat jenom písmena, čísla a oddělovač. Pro ten se nejčastěji používá pomlčka, protože podtržítko Google chápe jako spojovník (mysql_fetch_assoc bere jako jedno slovo, mysql-fetch-assoc jako tři).

Odstranění diakritiky se obvykle provádí vytvořením funkce obsahující výčet znaků s diakritikou a jejich varianty bez diakritiky. Následný převod zajišťuje např. funkce strtr. To není příliš elegantní – převodní tabulku jednak musíme ručně vytvořit a pokud se nechceme spokojit se znaky obvyklými v češtině, ale chceme převádět např. i cizí jména, bude poměrně obsáhlá a dá hodně práce, aby počítala se všemi znaky.

Mnohem elegantnější řešení nabízí funkce iconv sloužící k převodu kódování. Pokud k cílovému kódování připojíme //TRANSLIT, budou se nepřevoditelné znaky aproximovat (při použití //IGNORE se ignorují, jinak převod při nalezení prvního nepřevoditelného znaku skončí). Pro spolehlivou funkčnost je potřeba nastavit proměnnou LC_CTYPE funkcí setlocale na kódování UTF-8, např. tedy cs_CZ.utf-8.

<?php
/** Vytvoření přátelského URL
* @param string řetězec v kódování UTF-8, ze kterého se má vytvořit URL
* @return string řetězec obsahující pouze čísla, znaky bez diakritiky, podtržítko a pomlčku
* @copyright Jakub Vrána, https://php.vrana.cz/
*/
function friendly_url($nadpis) {
    $url = $nadpis;
    $url = preg_replace('~[^\\pL0-9_]+~u', '-', $url);
    $url = trim($url, "-");
    $url = iconv("utf-8", "us-ascii//TRANSLIT", $url);
    $url = strtolower($url);
    $url = preg_replace('~[^-a-z0-9_]+~', '', $url);
    return $url;
}
?>

V řetězci nahradíme každou posloupnost znaků jiných než podtržítko, číslo nebo písmeno (\pL) pomlčkou, kterou ze začátku a konce řetězce následně odstraníme. Řetězec převedeme do kódování us-ascii a na malá písmena. Na závěr odstraníme všechny znaky kromě povolených (protože např. á se při transliteraci převede na 'a).

Podotýkám, že sekvence \pL, která je pro převod také podstatná, je k dispozici až od PHP 4.4.0 a 5.1.0 a funguje pouze se řetězci v kódování UTF-8 při použití modifikátoru u.

Pokud bychom stejný problém chtěli vyřešit už na straně klienta v JavaScriptu, tak se musíme spokojit s primitivnějším postupem:

<script type="text/javascript">
var nodiac = { 'á': 'a', 'č': 'c', 'ď': 'd', 'é': 'e', 'ě': 'e', 'í': 'i', 'ň': 'n', 'ó': 'o', 'ř': 'r', 'š': 's', 'ť': 't', 'ú': 'u', 'ů': 'u', 'ý': 'y', 'ž': 'z' };
/** Vytvoření přátelského URL
* @param string řetězec, ze kterého se má vytvořit URL
* @return string řetězec obsahující pouze čísla, znaky bez diakritiky, podtržítko a pomlčku
* @copyright Jakub Vrána, https://php.vrana.cz/
*/
function make_url(s) {
	s = s.toLowerCase();
	var s2 = '';
	for (var i=0; i < s.length; i++) {
		s2 += (typeof nodiac[s.charAt(i)] != 'undefined' ? nodiac[s.charAt(i)] : s.charAt(i));
	}
	return s2.replace(/[^a-z0-9_]+/g, '-').replace(/^-|-$/g, '');
}
</script>

Viz také Transliterace azbuky.

Jakub Vrána, Řešení problému, 13.3.2006, on-line

Diskuse

Marek Prokop:

Mohu se zeptat, proč je URL kde-nas-najdete/ lepší pro vyhledavače než clanek.php?id=12? Mně to z hlediska vyhledavačů připadá úplně stejné.
13.3.2006 01:38:15

Tim:

Vyhledavacum je to asi jedno, ale pro uzivatele byva mnohem prijemnejsi, kdyz ma v url treba /clanky/z-domova/zase-snezi/ nez nejake zobraz.php?katerie=1&sekce=23&polozka=3456.
13.3.2006 02:40:25

neki:

Vyhledavačům je to asi stejně putna, jako uživatelům.

Vyhledavače na obsah URL v současné době více-méně kašlou, uživatelé taktéž.

Vyhledavač si hezké adresy nepamatuje o moc lépe než ty nehezké, uživatel stejně tak.

Mírná podobnost by tu byla.
13.3.2006 04:34:18

Birkof:

Vyhledavacum je to jedno, ale ne uzivatelum, kteri hledaji treba na google a pouziji operator inurl: napr.: "inurl:vytvoreni-pratelskeho-url". Jinak je to asi sumak, neda se ani moc oponovat s tim, ze se to lepe pamatuje, protoze si stejne nikdo nepamatuje, jak se jednotlive stranky jmenuji.
13.3.2006 09:06:44

mekele:

nezertuj... uzivatelu, kteri dokazi parametrizovat google query znam ve svem okoli asi 3
13.3.2006 11:08:37

Ivan:

Autor mal zrejme na mysli, ze lepsie je mat v URL klucove slova ako id=12 a pochybujem, ze na to kaslu, ako pise Tim.
13.3.2006 08:13:18

Rejpal:

A k cemu je SEO? Jistí třipísmenkoví odborníci na tom vydělavají a říkají, že je lepší mít cool url atd...

Nebo je SEO na prd a pár lidí na něm jen vydělává?

13.3.2006 08:27:11

pojízdná kočka:

Na Intervalu vyšel rozhovor se třemi předními (jak ty říkáš třípísmennými) odborníky na SEO (jsem líná to hledat) a vypadlo z nich, že pouze 9 % toho, jak vyhledávače vyhodnocují, je o vnitřních faktorech, a přátelská URL tvoří jen zlomek z oněch 9 %.
28.2.2009 08:26:20

ondrej:

protoze jsou v tom klicova slova, ze by SEO?
13.3.2006 22:28:18

ikona Jakub Vrána:

Opravdu to nebyl nejšťastnější příklad. Lepší příklad by byl třeba obrana-proti-sql-injection VS ?id=120.
24.3.2006 14:07:27

kriplozoik:

stránku "kde nás najdete" má skoro každá firma, organizace nebo společnost. Kdybych to zadal do Googlu, vyběhne jich dva a pul milionu, z čehož to, co hledám, bude nějakej 1'985'429tej odkaz.

A vůbec, zadávat do Googlu "kde nás najdete" je blbost.
10.9.2007 21:32:42

Aleš Halfar:

Pane Prokop, web na který tady odkazujete má lidsky čitelná url a vím, že se v této oblasti pohybujete více než dobře.. Nechtěl byste nám k tomu napsat něco více..? Díky
29.4.2009 06:34:30

Jan Bažant:

Osobní názor: Já url, ze které rámcově poznám o čem stránka je, vítám. A co je dobré pro uživatele, je dobré i pro vyhledávače ;-)
Ale samozřejmě je důležitější to, co je v článku psáno, než to, jakou má url.
13.3.2006 10:24:17

Trupík:

K čemu? Mít v url klíčová slova ne? Neřelk bych, že na to vyhledávače kašlou.
BTW, v ASP.NET to jde taky
http://trupik.aspweb.cz/programovani/csharp-…-aspnet.aspx
13.3.2006 10:35:25

Tomas Hodbod:

Re: Marek Prokop:
URL ../kde-nas-najdete/ z hlediska klic.slov lepsi nez URL ../clanek.php?id=12 prilis nebude. O hodnote URL ../zdravi-vyziva/ oproti ../clanek.php?id=12 asi lze jenom polemizovat.

Ale z vlastni zkusenosti bych rekl, ze friendly-url (ktere se tvari jako staticke) maji vyhledavace radeji predevsim z toho duvodu, ze je lepe (rychleji) indexuji nez adresy dynamicke s parametry v URL.
13.3.2006 11:18:24

Marek Prokop:

Ano, Tomáši, to jsem tím chtěl říci. URL kde-nas-najdete má přínos jen pro uživatele, z hlediska SEO je k ničemu. Je dost nešťastné, že se SEO často redukuje jen na technické prostředky, a zapomíná se, že mnohem důležitější je obsah -- i v případě URL.
13.3.2006 13:07:40

ondrej:

no ale zrovna seznam.cz mam pocit hraje hodne na hezka url a posouva je vyse
13.3.2006 22:31:00

ikona spaze:

A kdo bude hledat klicova slova "kde", "nas", "najdete"?
17.3.2006 14:45:36

ondrej:

no a vsechny ostatni hledat budou ("vysavace", "pocitace")
je videt ze seznam ukazuje nahore ty co maj slovo v url

a asi ne jen seznam
20.3.2006 18:09:17

adrive:

Mne ta transliterácia nič nerobí. Môžete ma nakopnúť, kde by mohla byť chyba? žiadne á sa nenahradí za 'a, ale úplne sa vynechá.

Díki
14.3.2006 14:15:07

ikona MISHAK:

No jedno to není, těžko ale posoudit jestli je výhodnější při změně struktury webu přeindexovávat z indexů článků na názvy nebo naopak.

Varianta s CoolURL mi příjde lepší i z hlediska bezpečnosti a přehlednosti.

Ještě jedna věc: V době "rychlého internetu/TeleComu" je stále nejdůležitější tag title resp. titulek a adresový řádek je hned pod ním ;-)

S tou indexací bych si tak jist nebyl rychleji není lépe a naopak. A jak expert(i) z H1 tvrdí, že se má v CoolURL slovo oddělovat znakem - (mínus) a ne _ (podtržítkem), což je vlastně spojovací znak (odkojenci pascalu máme jiný názor). Takže je to buď chytrý marketingový tah, nebo pravda (jinak by to nemělo smysl... i když co má...)
17.3.2006 17:39:41

ikona Jakub Vrána:

Nechápu část začínající "A jak expert(i) z H1 tvrdí". V článku je přeci uvedeno totéž, proč to je i v komentáři?
17.3.2006 17:42:40

ikona MISHAK:

To je jen osobní ftípek narážející na jejich poučování :)
20.3.2006 17:38:15

Leo:

Muzu pridat vlastni zkusenost s pouzitelnosti URL pro lidi. Potreboval jsem si zapamatovat adresu konkretniho clanku na intervalu, driv tam bylo cislo (asi id, uz nevim), a ted je tam dlouhatansky nazev clanku se slovy oddelenymi pomlckami. Sice hezky, ale nezapamatovatelny. Osobne se mi libi kombinace, kdy se na zacatku objevi cislo (a staci pro zadani URL) a za nim je teprve to kecani pro vyhladavace, neco jako

www.example.com/1345-jsou-dlouhe-url-k-necemu

pricemz funguje i

www.example.com/1345

Leo
18.3.2006 14:48:59

l:

to se povazuje za chybu, protoze pak je mozne vytvorit silene adresy typu:

www.example.com/1345-karel-gott-je-gay
2.5.2006 22:41:14

ikona Jakub Vrána:

www.example.com/1345-cokoliv je v tom případě samozřejmě nutné následně přesměrovat na www.example.com/1345-spravne-url. Ale např. Novinky.cz to mají špatně.
2.5.2006 23:59:39

uzivatel:

Cislo je vseobecne lahsie pamata.
415-nazov-clanku je jedna z najlepsich moznosti tvorenia odkazu, pretoze sa velmi lahko z toho da zistit cislo clanku pouzitim funkcie intval(). ak narazi na prvy znak nevyhovujuci ciselnej hodnote tak dalej pokracovat nebude.
cize hned dostanem cislo 415 a nemusim to robit cez zlozite regularne vyrazy alebo rozdelovanim na polia.
toz moj prispevok :)
18.5.2006 20:48:53

uzivatel:

a samozrejme. cisla clankov sa nemenia. pricom nazvy ano. a to je najvacsia chyba pri pouziti SEO. ak premenujem nazov clanku  tak vsetko co uz zaindexoval vyhladavac alebo mam v pamati prehliadaca mozem poslat viete kam ;)
ale ID clanku tazko budem menit
18.5.2006 20:51:42

kriplozoik:

A kde přesně použiješ tu intval()? V php kódu? Asi sotva.
Navíc, adresa "/123-cokoli" to není tak úplně jednoznačná (resp. není jednoznačné, že je nejlepší). Představ si, že jsi v cizím internet café a máš do adresového řádku vyťukat chtěnou URL. Možná si zapamatuješ nadpis článku, možná budeš schopen ho přepsat do "cestiny" a mezery nahradit pomlckama, ale pamatoval si i to dlouhý číslo? Těžko, Anežko.
10.9.2007 21:50:21

ikona Jakub Vrána:

Pokud se přepis realizuje přes mod_rewrite, což je obvyklá volba, tak jsou "složité regulární výrazy" v ceně. Zbytek URL je navíc potřeba taky získat kvůli zmíněné kontrole nesmyslného URL.
18.5.2006 23:26:25

kriplozoik:

tak je jde vytvořit - no a co? pokud občas nějakou takovou adresu známý známému předá v mailu nebo v icq (a pokud se i tak přesměruje správně), kde je problém?
10.9.2007 21:59:04

Hever:

iconv se, mám pocit, musí nějak přiinstalovávat, nemám pravdu? http://www.php.net/manual/en/ref.iconv.php

Hezká URL opravdu nepomahají k SEO? Já myslel, že ano.

I kdyby něměly v SEO smysl, myslím, že uživateli mohou pomoci, například teď se mrknu do adresního řádku a hned vím, k jakému článku vlastně ten komentář píšu. Další výhoda se jeví u ruzných indexovacích udělátek .. když vím, že lidé hodně klikají na ?id=452, moc mi to ke štěstí nepřidá.

A ještě: například v němčině by se měly některé znaky přepisovat do bezdiakritické verze do dvou znaků (např. "a s dvojtečkou nahoře" by se mělo v případě německého jazyka přepisovat jako "ae") ... a tím si iconv předpokládám neporadí ..?
28.3.2006 04:08:39

ikona Jakub Vrána:

Hezká URL SEO pomáhají, Marek Prokop asi narážel na nevhodně zvolený příklad (lidi nehledají "Kde nás najdete").

ä se přepíše na "a, celá tabulka je třeba na http://cvs.sourceforge.net/viewcvs.py/libiconv/…?view=markup.
28.3.2006 13:40:08

PD:

Tak se koukni o 2 centimetry výš na horní okraj okna prohlížeče - máš tam TITULEK stránky, který by měl jaksi z principu být ještě lepším vodítkem, "kde jsi", než debilní URL.
30.9.2009 10:32:57

Pubso:

K tým adresám...
http://vyhledavace.info/seo-faq/16/seo-url
28.3.2006 21:43:48

Vita:

Mohl byste sem dat priklad jak prevest url clanek.php?id=12 na kde-nas-najdete/? Nejak jsem to z toho mod_rewrite nepochopil. Dekuji
10.4.2006 15:57:34

ikona Jakub Vrána:

Do tabulky s články přidáte další sloupec `url`, mod_rewrite nastavíte tak, aby kde-nas-najdete/ převedl např. na clanek.php?url=kde-nas-najdete a v clanek.php získáte článek podle tohoto parametru.
10.4.2006 16:15:56

Vita:

Mohl byste dat jeste kousek kodu porad me to nejak nemuze nakopnout ;-). Proc tam musim pridavat ten dalsi sloupec? Na co je mi teda ta funkce na odstraneni diakritiky, kdyz uz to muzu do databaze zadat rovnou v tom formatu v jakem chci tzn. bez diakritika a s pomlčkama.
10.4.2006 18:33:26

ikona Jakub Vrána:

Funkce slouží pro automatické vytvoření URL z nadpisu. Výhody a nevýhody ručního řešení jsou popsány na začátku článku.
10.4.2006 18:45:06

Vita:

Aha tak to jsem nejak prehledl omlouvam se. Je tedy mozne mod_rewrite nejak nastavit primo v kodu PHP? Co kdyz mam stranky na hostingu a tam nemam pristup na nastaveni Apache.
10.4.2006 18:57:05

ikona Jakub Vrána:

Ne. mod_rewrite je modul Apache a je nutné ho nastavit v konfiguraci Apache (např. v .htaccess). Pokud vám hosting mod_rewrite zapnout nedovoluje, zvolte jiný, nabídka je široká.

Problém s přepisem URL se dá vyřešit i přes chybovou stránku, takže pokud vám hosting dovoluje nastavit alespoň tu, tak to řešitelné je.
10.4.2006 19:11:49

Vita:

Mohu Vás tedy jeste pozadat jaky kod mam zadat do .htacces jeste jsem ho nepotreboval pouzit tak nevim jak nato. Chtel bych se pokusit o pratelska url a jinak se mi to asi nepodari :-). Dekuji za veskere informace.
10.4.2006 19:25:00

Vita:

Neco jsem nasel. Myslim ze to pomuze i ostatnim. Kazdopadne diky za info.
http://seky.nahory.net/2004/12/staticke-stranky/
10.4.2006 19:48:39

Lukas Mach:

Pokud nekomu pripada pozadavek na PHP 4.4.x prilis omezujici a pritom se mu opravdu nechce sestavovat konverzni pole pro strtr, muze se podivat do zdrojoveho kodu textpatternu na funkci dumbDown() v souboru txplib_misc.php a na ini soubor i18n-ascii.txt, oboji v adresari lib.

Osobne povazuji za pekne, kdyz jsou ze zkratek odstraneny pomlcky. Vetsinou se z "firma s.r.o." stane "firma-s-r-o", pritom "firma-sro" je asi hezci.
2.5.2006 22:58:24

Fak:

zajímalo by mě co s takovým vietnamským řetězcem, protože tahle funkce funguje dokud tam nepřijde něco jako toto:
"đạo của Khmer Đỏ"
to bohužel vyhodí jen "d" :(
při použití //IGNORE to vyhodí dokonce už "o-ca-Khmer-"
to znamená, že si budu muset sehnat celou vietnamskou abecedu?:((

Díky za rady
14.5.2006 23:24:34

ikona Jakub Vrána:

Problém je v tom, že ạ a další vietnamské znaky nemají v libiconv transliteraci. Zkusil bych poslat patch třeba na bug-gnu-libiconv@gnu.org, ale je to běh na dlouhou trať.
15.5.2006 14:13:34

Fak:

to asi opravdu nemá cenu, pokud by už nějaký release vydali, tak bych musel čekat, než ho aplikují na hostingu...

Už jsem si našel - snad - všechny takové vietnamské znaky a hurá do pole...
16.5.2006 03:42:32

kriplozoik:

Ale no dobře. Abych zase nebyl tak neurvalý, tak bych se místo toho mohl podělit o druhé řešení -

URL sice automaticky ukládat, ale v administračním rozhraní ho nabízet k editaci. Přidaná agenda odkazů bude v podstatě nulová (administrátor ho může ignorovat), dokud generované URLs vypadají pěkně. V případě jánevim tradiční čínštiny pak nastává ještě starost o zvolení latinkové URL.

(I když podle mě, v případě tradiční čínštiny, bych řekl, že by byly skoro lepší adresy typu /?article=12345, co myslíte?)
22.9.2008 16:17:15

kriplozoik:

V kolika procentech případů je v názvu článku "ạ"?
Statisticky bezvýznamné.

p.s. mimochodem, nevím jak je to u exploderáků, ale uživatelům firefoxu stačí napsat jedno dve písmena adresy serveru a vybrat si z nabídky ten správný článek, který v minulosti načetli, tím, že se dívají do pravé části vysouvacího menu, kde se jim vypisuje to, co odpovídá <title> stránky. No nevím, ale myslím, že (zvlášť pokud něco takového má i M$ Exploder, tak) tím friendly URL podstatně ztrácejí na tom argumentu, že se dají lépe zapamatovat (protože si je stejně nikdo nesnaží pamatovat a vybírá je výše zmíněným způsobem)
10.9.2007 22:04:49

ikona Jakub Vrána:

Statisticky bezvýznamné to je jen do té doby, než zprovozníš vietnamskou verzi webu.
11.9.2007 13:10:57

kriplozoik:

Zkus z hlavy vyjmenovat 5 jakýchkoli českých stránek s vietnamskými lokalizacemi...
9.3.2008 03:48:24

zbynek riha:

to s tim ale nema nic spolecneho :D
5.6.2008 01:45:39

kriplozoik:

Ale má. (ale to už je jiná bitva - (akademické vs. praktické)) :]

Btw. v článku to je naznačeno, ale ne na plná ústa řečeno, že v případě JavaScriptu to primitivnější řešení zřejmě nikdy pokryje všechny případy. Ať se koukám, jak se koukám, např. ono "ạ" tam nevidím.
22.9.2008 16:11:25

onge:

to sice nepokrije, ale zase se to dela v momente, kdy pises nazev clanku a mas moznost pripadne nesrovnalosti opravit. JavaScript nema byt spasne reseni, ma ulehcovat praci, no a to tohle bezpecne dela:)
31.12.2008 09:11:23

kriplozoik:

Tak to si tedy nerozumíme. Nevidím nikde v Jakubově příspěvku, že javascriptové řešení něco dělá, "když píšeš název článku." A i kdyby ano, tak to opět nebude dělat dokonale, protože ono vietnamské ạ přeloží blbě (resp. vůbec). V takovém případě mi přijde lepší provést (pořádnou) transliteraci na straně serveru, a nedrbat se ještě navíc s nedokonalým nahrazováním v javascriptu. V takovém případě javascript práci neulehčuje ale naopak přidělává :-(
8.2.2009 23:18:36

uzivatel:

Zdravim.
Tak mam este jeden problem.
ako vyriesit prevod do ASCII ak je u iconv() pouzita kniznica glibc, ktora to nejako nedokaze
pricom co mam na locale libiconv tak tej to nerobi problem
18.5.2006 23:13:38

ikona Jakub Vrána:

Zkus před převodem zavolat <?php setlocale(LC_CTYPE, "cs_CZ.utf-8"); ?>.
6.12.2007 13:51:31

David Grudl:

Podotýkám, že tohle nefunguje vždy.
31.3.2012 09:00:35

ikona dgx:

> Podotýkám, že sekvence \pL, která je pro převod také podstatná, je k dispozici až od PHP 4.4.0 a 5.1.0 a funguje pouze se řetězci v kódování UTF-8...

Jakube, když už provádíš transliteraci na ASCII přes iconv, není lepší vkládání pomlček umístit až za iconv a vyhnout se tak použití \pL? Padlo by tak nepříjemné omezení na PHP 5.1.0
26.6.2006 16:02:53

ikona Jakub Vrána:

Problém je v tom, že transliterace do řetězce vloží nadbytečné znaky, které je následně potřeba odstranit. Např. "bá" se převede na "b'a" a následný převod na pomlčky z toho udělá "b-a", což je samozřejmě špatně.

Ve starších verzích PHP by se dal udělat výčet znaků, které se při transliteraci používají, nahradit je za pomlčky předem a po převodu je odstranit.
26.6.2006 16:51:33

ikona dgx:

Pravda, pravda.

Řešívám to tak, že pomlčkama nahrazuji pouze mezery a ostatní "bordel" odstraním, což pak funguje i s transliterací před zpracováním. Ale nejde o tak obecné řešení.
26.6.2006 18:13:16

Paces:

Myslím, že přáteslká url jsou vždy lepší pro uživatele. Třeba když citujete (např. v diplomce) z weborých stránek, tak lépe v seznamu literatury vypadají smysluplné url než jen stejná url s rozdílnými ID.
4.7.2006 16:22:55

PD:

Asi tak stejně jako v seznamu literatury budou hůře vypadat

Sborník LŠ 2005, s.237
Sborník LŠ 2006, s.246
Sborník LŠ 2007, s.112

??

Možná to v seznamu vypadá lépe, když jsou tam "friendly URL", ale pokud už nějaký chudák bude mít tištěnou verzi a bude z ní muset ta URL opisovat, tak

web.cz/?id=135
naťuká rychleji a s méně překlepy, než
web.cz/historie-integrace-romskeho-entika-do-majoritni-spolecnosti-p3y

Kapiš?
30.9.2009 10:39:08

kozotoč:

pokud to píšeš na počítači a ne na psacím stroji, tak adresy napíšeš stylem Ctrl+C, Ctrl+V. Bez překlepů, úplně stejně rychle. A opravdu to vypadá lépe.
9.2.2010 21:56:41

PeTa:

Měl bych prosbičku, spíš se týkající samotného mod_rewrite:

na localhostu (winxp,apache2.2.0(+php+mysql)) se mi těžce nedaří rozběhnout mod_rewrite (paradoxně na webhostingu je vše OK)

modul je správně načten a funkční (ověř. např. pro ErrorDocument 404 / missing.html), ale pokud provedu RewriteRule (syntakticky snad v pořádku?):

RewriteRule ^(.*)\.html$ /index.php?wiev=$1 [L,QSA]

vyflushne mi to jen prázdný dokument. Čiže podstrkovaný dokument to najde, ale nezobrazí. Pokud odkážu na neRewritovaný soubor, hodí to správně 404. Předpokládám, že mám něco špatně v lokálním httpd.conf, ale už jsem s rozumem v koncích. Jo a krom toho se někam ztratí REFERER.

Dík, pokud někdo víte, kde mám chybu. PeTa
23.8.2006 16:54:03

ikona dgx:

1) Zkus si do index.php vložit <?php phpinfo() ?> a ověř, zda máš všechny parametry předané správně (wiev má být asi view, ne?)

2) Zkontroluj cesty, pokud nastavuješ pres .htaccess, aby by nemělo být použito /index.php ale index.php.
23.8.2006 18:40:39

PeTa:

tak jsem z toho phphinfo() nezmoudřel:
REDIRECT_QUERY_STRING     wiev=faq
REDIRECT_URL     /Pages/h-xl/faq.html
QUERY_STRING     wiev=faq
REQUEST_URI     /Pages/h-xl/faq.html
SCRIPT_NAME     /Pages/h-xl/index.php
_REQUEST["wiev"]    faq
_SERVER["REDIRECT_QUERY_STRING"]    wiev=faq
_SERVER["REDIRECT_URL"]    /Pages/h-xl/faq.html

-  jasně, mělo tam být správně "vjú", musím to opravit ve všech skriptech. Lomítko před indexem už v rewrite nemám. Stejně je ale nadále výstupem prázdný list.
24.8.2006 10:58:14

ikona dgx:

V tuto chvíli máš jistotu, že se skutečně načítá skript /Pages/h-xl/index.php s parametrem wiev=faq, a tedy problém v mod_rewrite není. Tedy je na čase hledat problém jinde.
24.8.2006 15:33:19

PeTa:

To dgx:
Dík za radu. Už mi to maká. Máš pravdu, že v mod_rewrite chyba nebyla. Problém byl úplně někde jinde (i když stejně tak nepochopitelný). Stránka index.php obsahovala někde ve struktuře reklamní banner reprezentovaný skriptem: <script type='text/javascript'>/* <![CDATA[ */
bla bla bla //]]></script>, který buď způsoboval zacyklení mod_rewrite, nebo nějakou jinou neplechu. Každopádně výstupem byl buď prázdný list, nebo shozený Apache. Jakmile jsem CDATA vyhodil, pracuje vše OK. Jen jsem to hledal 3 dny a důvod proč se to tak chovalo mi uniká dosud.
28.8.2006 13:03:34

Peter Kytlica [www.pixo.sk]:

A čo takto radšej napísať článok ako jednoducho napísať mod_rewrite ??

Hľadám to na webe celú noc a konečne keď som si myslel, že to mám, kecá sa tu o blbosti.
7.9.2006 09:28:11

ikona dgx:

No, Jakube, šup, napiš článek. Že se nestydíš psát o takových blbostech, když Péťa celou noc hledá něco jiného?

7.9.2006 10:56:35

Ján Koštial:

Celkom by ma zaujímalo, ako uspokojivo vyriešiť generovanie priateľského URL na multijazyčných stránkach, kde sú texty uložené v DB a stránky sa generujú podľa zvoleného jazyka. Prevádzkujem stránky, kde generujem obsah cez jediný skript http://www.mojadomena.sk/index.php?stranka=…_parameter=yyy,...]). O tom, či ten spôsob je vhodný alebo nie sa diskutovalo v inej téme, ale teraz o inom.
Povedzme, že predávam lietajúce stroje a chcem generovať priateľské URL. Takže stránku pomenujem http://www.domena.org/lietadla-bezmotorove-jednomiestne.php.
Stránky prevádzkujem napr. v šiestich jazykoch - teda by mala existovať aj stranka http://www.domena.org/aeroplanes-sailplanes-single_seater.php. (A ďalšie štyri v ďalších jazykoch.)
Bolo by dosť od veci aby tie skripty fyzicky existovali aj ako súbory na disku, aj keby len volali nejaký spoločný skript. Totiž otázka znie: Čo keď chcem pridať jazyk? Čo keď chcem rozšíriť sortiment o lode? Ako zabezpečiť, aby tie priateľské URL v rôznych jazykoch spracovával stále ten istý skript? (.htaccess?)
12.9.2006 11:40:11

ikona Jakub Vrána:

Nejjednodušší řešení nabízí mod_rewrite, který slouží právě k přepisu URL. Stačí cokoliv přepsat na index.php a původní URL předat v parametru. Článek o tom vyjde v pondělí.
12.9.2006 12:32:38

ikona dgx:

Ne, Jakube, původní URL je nejlepší získat z $_SERVER['REQUEST_URI']. Nemusíš tak vůbec narušit parametry, nedojde ke kolizi atd.

Jinak více než "přepisovat vše" je elegantní "přepisovat vše neexistující". Aby se legalizovaly požadavky na obrázky, styly, skripty atd. Tedy třeba takto:

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule . controller.php [L]
13.9.2006 06:09:19

ikona Jakub Vrána:

$_SERVER['REQUEST_URI'] je druhé možné řešení, jen je potřeba nezapomenout na to, že skript musí při zkoumání URL uříznout původní parametry.

Pokud se přepisuje vše neexistující, je potřeba zabezpečit skripty proti přímému spuštění. Proto raději přepisuji vše a to, co se přepisovat nemá (favicon.ico, robots.txt, static/) explicitně vyjmenuji.
13.9.2006 12:15:37

kozoslon:

můžete uvést příklad (kus kódu v .htaccess)?
8.3.2008 01:51:55

Tomas:

Pouzivam smerovani vsech .html stranek na index.php pres mod_rewrite preposilam na index.php url jako parametr kde jej
pres explode('/',$_GET['page']); ulozim do pole.

tim muzu mit jazykove mutace s url napr.: www.domena.cz/cz/letadla/bezmotorova-jednomistna.html
www.domena.cz/en/aeroplane/engineless-single.html

neni pak tezke si z mysql vytahnout id stranky plus url pro vsechny jazykove verze tak, ze okdaz na jiny jazyk me hodi stejnou stranku jen v jinem jazyce.

Osobne si myslim ze hezka URL muzou mit vyznam pro vyhledavace pokud vnich uvedete spravna klicova slova.
navic si myslim ze pro SEO je vyhodnejsi mit .html stranku nez .php

11.1.2007 13:08:57

Honza:

Zrovna jsem si takovy web napsal. Mám jednu tabulku se "systémovými" údaji o všech článcích, pak pro každý jazyk zvlášťní tabulku (podle mě je to rozumnější řešení než na to mít sloupce v jediné tabulce) a nakonec tabulku pro přepisování adres, kde je PK(id_clanku, jazyk), adresovy_retezec.
15.2.2007 13:00:04

Onecar:

Dneska jsem na intervalu četl, že google velmi špatně url, které mají v osbě více než 2 parametry. Proto je lepší vytvářet hezké friendly URL.
30.9.2006 17:31:59

jann:

mam problem s iconv("utf-8", "us-ascii//TRANSLIT", $url);
Nepřevede mi to znaky s diakritikou na apostrov a bez diakritiky, ale misto toho to da otaznik (3f hexa)
18.1.2007 00:05:50

ikona dgx:

Na některých hostinzích se to stává. V takovém případě je lepší k transformaci použít převodní tabulku (viz http://www.dgx.cz/trine/item/odstraneni-di…-ruznych-kodovani)
18.1.2007 05:29:52

jann:

Aha, takže to je chyba hostingu jo? Jsem to právě chtěl na převod nadpisu ve fóru na url a celkem se mi hodilo že to obsahovalo všechny znaky a převyprávělo to třeba & atd... Nikdy člověk neví co zadá uživatel jako nadpis tématu...
18.1.2007 11:17:48

Andrew:

Myslím, že tento "problém hostingů" se dá ve většině případů vyřešit nastavením locale na utf8, na což Jakub v článku upozorňuje.
A když jsme u těch převodních tabulek, tak můžeme převést rovnou celé utf8 - tabulky jsou k dispozici. Zabavilo mě to na dlouho si pročítat přepisy všech možných čínských, arabských a já nevím jakých znaků. Soubor je ale kapánek větší. ;-)
23.7.2008 00:53:24

jann:

Zjistil jsem v nejakem foru, ze tento problem je pri pouziti knihovny glibc a ze pry s libiconv to funguje spoleglive. Napsal jsem na hosting jestli to vymeni, ale chteli by nejaky odkaz na buglist nebo neco takoveho, nemate nekdo?
18.1.2007 15:41:09

vazba:

Pokud máš hosting s glibc, lze to vyřešit tak, že před voláním friendly_url() zavoláš ještě funkci cs_win2ascii() od DGX, viz. http://latrine.dgx.cz/odstraneni-diakritiky-z-ruznych-kodovani
31.5.2009 19:24:06

ikona Jakub Vrána:

Viz http://php.vrana.cz/vytvoreni-pratelskeho-url.php#d-5672.
1.6.2009 07:27:01

Gioel:

Chcel by som sa opytat mne ta funkcia nefunguje.. a nesprava sa tak ako by som chcel...
Ukazka:
http://www.powerplaymanager.com/test/test_seo_url.php
Prvy je nazov stranky druhy je URL vytvorena mojou fukciou:
pozriet je mozne tu:
http://diskuse.jakpsatweb.cz/index.php?action=…&topic=43493
9.2.2007 23:35:33

abysser:

"Pěkné URL" je především taková hezká "standardizační" forma odkazování. A i když původním záměrem mohla být přehlednost, bezpečnost nebo SEO, určitě je to dobrý návyk a z hlediska lidského myšlení přirozenější předávání parametrů hierarchickým ergo logickým stylem, než psat všude ampersandy, středníky či jiné oddělovače a vyjmenovávat čtenáři všechny názvy GET proměných, které časem třeba změníme, ale naše pěkné "adresářové" URL už tu bude na věky věkoucí ;)...

Já bych uvítal článek spíše psychologicko-filosofický a to takový, který by se věnoval především tedy z toho uživatelského hlediska nejlepší technice potvrzování komentářů proti spamům. Osobně totiž nesnáším rozpoznávání mnohdy nerozpoznatelného textu v obrázku, doplňování rovnic a vyplňování nospam ;). 1. něco vypňovat? 2. kontrolovat v pozadí (keyword/IP blacklist) 3. sekundární potvrzení kliknutím? Jaké je nejlepší z uživatelského hlediska a zároveň bezpodmínečné pro spam toť otázka.
24.2.2007 20:04:27

ikona Jakub Vrána:

Zatím docela dobře funguje automatické vyplňování kontrolní otázky JavaScriptem. Někdo si taky pochvaluje odeslání ve dvou krocích (náhled, dokončení).
25.2.2007 14:36:58

dawid:

Warning: preg_replace(): Compilation failed: PCRE does not support \L, \l, \N, \P, \p, \U, \u, or \X at offset 3

Dobry den nemohl by mi nekdo poradit s touto chybou.... nebo nejake jine reseni.. dekuji
21.3.2007 12:29:10

ikona Jakub Vrána:

Pravděpodobně používáš starou verzi PHP, resp. knihovny PCRE.
21.3.2007 12:38:34

ikona SUK:

Aby to vypadalo lepe, je vhodne aby se znaky ani neopakovaly (hlavne ty pomlcky)
<?php
  $title
=preg_replace("/(.)\\1{0,}/","\\1",$title);
?>
//pokud uz to tu nekdo psal, tak se omlouvam ze to opakuji
16.4.2007 23:13:33

ikona Jakub Vrána:

Kde se v kódu ty pomlčky podle tebe budou opakovat? Kód <?php preg_replace('~[^\\pL0-9_]+~u', '-', $url); ?> přeci nahradí jakoukoliv posloupnost nepísmenných znaků jednou pomlčkou.

Tvůj kód naopak třeba z Google udělá Gogle, což jistě nechceš.
17.4.2007 03:09:18

ikona SUK:

No jo pravda, sorry.
A uz stejne pouzivam jiny kod :)
29.5.2007 11:47:05

Uncode:

Jak muzu prevest retezec "DĚLAT" na "dělat"? S ceskymi znaky je problem.
21.4.2007 04:19:02

ikona Jakub Vrána:

Viz http://php.vrana.cz/prevod-na-velka-pismena.php.
21.4.2007 10:31:57

darkcraft:

Dobry den,
predem bych chtel podekovat za kod, ktery mi velmi pomohl, takze - dekuji.
Nasel jsem v nem vsak jeden maly nedostatek. Treba ja delam SEO na webu, ktery pouziva v nadpisech ceska znamenka. Pouzitim vaseho kodu mi tedy vznikl napriklad z retezce "Mapování struktury webového serveru" retezec "mapovn-struktury-webovho-serveru", coz neni moc vhodne, proto jsem si vas kod dovolil vylepsit, uprava je v tom, ze pred vlastnim replacem podle regexpu nahradim diakriticke znaky za nediakriticke. Takze na zacatek vlozim tento kod:

$cz = array("ě", "š", "č", "ř", "ž", "ý", "á", "í", "é", "ť", "ú", "ď", "ů", "ň");
$noncz = array("e", "s", "c", "r", "z", "y", "a", "i", "e", "t", "u", "d", "u", "n");
$url = str_replace($cz, $noncz, $nadpis);

pak mi z jiz zminovaneho prikladu vznikne retezec "mapovani-struktury-weboveho-serveru", coz je podle me mnohem prijatelnejsi..
29.5.2007 07:16:21

ikona Jakub Vrána:

Hlavní náplň kódu je právě v odstranění diakritiky. Stará se o to řádek <?php iconv("utf-8", "us-ascii//TRANSLIT", $url); ?>. Pokud ti nefunguje, máš nejspíš něco špatně (řetězec není v kódování UTF-8 nebo není správně nainstalované iconv). Tvůj kód má tu nevýhodu, že funguje pouze pro české znaky a třeba slovenské ľ mu proklouzne.
29.5.2007 12:48:07

darkcraft:

Aha, no mate pravdu, ale potom tedy bude asi chyba v nainstalovanem iconv, protoze retezec samozrejme v UTF8 je..
30.5.2007 00:45:22

naco:

melo by pomoci zadat setlocale(LC_CTYPE, 'cs_CZ')
24.8.2007 00:13:28

naco:

Rad bych se zeptal, proc pouzivate $url = preg_replace('~[^\\pL0-9_]+~u', '-', $url), kdyz iconv vsechny znaky krome .-_ pismen a cislic ignoruje. Sam pouzivam jednodussi:
$url = ereg_replace('[ ]+', '-', $url);
$url= iconv('UTF-8', 'ASCII//TRANSLIT', $url);
a zatim jsem nenarazil na problem. Ma nekde moje reseni slabinu?
24.8.2007 00:23:20

ikona dgx:

iconv utf-8 -> ascii nefunguje správně na řadě (ze zkušenosti spíš většině) hostingů. Do řetězce vkládá znaky jako - ' apod. Ne vždy je to akceptovatelné.
24.8.2007 01:54:44

naco:

jasny, diky za odpoved. asi mam stesti na hosting :-)
3.9.2007 21:58:49

ikona Čuga:

mel bych drobny dotaz...

nemam text v utf-8... lze funkci upravit pro jine kodovani??? nebo spis jak prevest z Win-1250 na utf-8???

diky za odpovedi
28.8.2007 03:11:27

ikona Čuga:

pomoci prevodnich fci od dgx sem prevedl z win-1250 na utf-8...

ovsem dalsi problem :) necekane... ě presoupnul na 283, tak stejne u ř a č (samozrejme s jinymi kody)...
28.8.2007 03:49:53

Štěpán Svoboda:

Ještě by možná stálo za doplnění do článku že se musí nastavit locale, jinak při použití TRANSLIT budou akcentovaná písmenka vynechána bez jakékoliv chyby a při použití IGNORE bude vyhozeno notice Ilegal character.
3.10.2007 23:08:53

ikona Jakub Vrána:

Na co by se podle tebe mělo nastavit locale? Mě vše korektně funguje i bez jakéhokoliv nastavování a nevím, že by to s tím mělo co do činění. Uveď nějaký příklad.
5.10.2007 18:19:04

Štěpán Svoboda:

heh :) omlouvám se za delší interval...
Pokud nejsou nastavené locale např:

setlocale(LC_ALL, 'cs_CZ.UTF-8');

ale je to fuk - mohou být třweba německá - funguje to stejně. Potvrdilo se mi to po delší době na zcela jiném počítači: Jak jsem psal: Pokud nejsou nastavena locale české a zřejmě i jiné znaky jsou vynechány bez jakéhokoliv varování.
3.3.2008 19:01:34

Štěpán Svoboda:

Transliterace totiž závisí na použitých locales. Zkuste si převést "Bürgerlich" s českými locales a s německými.
3.3.2008 19:45:02

ikona Honza:

Ahoj, mám problém s preg_replace na jednom hostingu. Např z 'H13a' preg_replace('~[^\\pL0-9_]+~u', '-', $url); vytvořil '13-' . Je to pouze na jednom hostingu, nevíte, kde by mohla být chyba (PHP Version 5.1.6)
18.10.2007 18:50:58

ikona Jakub Vrána:

Příčina bude pravděpodobně v použití knihovny glibc místo libiconv. Řekne ti to phpinfo().
18.10.2007 18:52:58

ikona Honza:

Je to glibc. Je tedy nějaká možnost toto napravit?
19.10.2007 03:01:01

ikona Jakub Vrána:

Požádat hosting o změnu. Pokud nevyhoví, tak změnit hosting. Pokud se ti nechce, budeš muset funkci napsat ručně (podobně jako ve verzi pro JavaScript).
19.10.2007 14:01:17

ikona Honza:

No s hostingem to právě řešíme a i oni zatím neznají řešení:
"Bohuzel mam k dispozici na
vyzkouseni jiny stroj kde je u iconv take glibc a tim to neni, jelikoz mi ten
vas preg_replace normalne funguje.
Rozdil tam vidim pouze v PHP - 5.1.6 vs. 5.2.0 a v knihovne na regularni
vyrazy PCRE - 6.6 vs 6.7"

Vypadá to, že problém nastává ještě před tím, než se skript dostane k knihovně iconv - ted již v preg_replace... ???
19.10.2007 14:16:54

ikona Jakub Vrána:

No jistě, omlouvám se za zmatení. Nějak jsem si špatně přečetl první příspěvek a místo preg_replace() četl iconv(). S tímhle problémem použitá knihovna samozřejmě nesouvisí.

\pL by nicméně mělo být k dispozici od PHP 5.1.0 a mezi PCRE 6.6 a 6.7 jsem také žádnou opravu související chyby nenašel, takže bych si na to nevsadil. Ale vyloučit to nemohu.
19.10.2007 14:39:20

ikona Honza:

Díky Jakube, tak lidé z hostingu už na to přišli:"Problem byl v uvozovkach. Kazde PHP se k
tomu muze stavet jinak, u nas funguje nize uvedena verze."

$url = preg_replace("'~[^\\pL0-9_.]+~u'", '-', $url);

19.10.2007 16:03:17

ikona Honza:

Aha, tak zřejmě to sice řeší problém s vymazáním znaků, ale funkce je poté nepoužitelná
19.10.2007 16:15:53

ikona Jakub Vrána:

Uvedený kód je bohužel nesmyslný. Apostrof v tomto výraze slouží jako oddělovač modifikátorů a hledá se tedy regulární výraz ~[^\\pL0-9_.]+~u. S verzí PHP to nijak nesouvisí.
19.10.2007 16:43:11

iguana007:

Taky jsem měl problém s regulárním výrazem... pouzil jsem fci takto:
<?php
function prevod_textu_na_url ($url) {
    $url = preg_replace('~[^\\pL0-9_]+~u', '-', $url);
    $url = trim($url, "-");
    $url = iconv("utf-8", "us-ascii//TRANSLIT", $url);
    $url = strtolower($url);
    $url = preg_replace('~[^-a-z0-9_]+~', '', $url);
    return $url;
}
$foo = "Testovací sktipt ěščřžýáíé!?.:.-";
print
prevod_textu_na_url($foo);
?>

coz mi vracelo pouze písmeno p ... pomohla změna fce na toto:
<?php
function prevod_textu_na_url ($url) {
    $url = iconv("utf-8", "us-ascii//TRANSLIT", $url);
    $url = strtolower($url);
    $url = preg_replace('~[^a-z0-9_]+~', '-', $url);
    $url = trim($url, "-");
    $url = preg_replace('~[^-a-z0-9_]+~', '', $url);
    return $url;
}
?>
v podstatě jde jen o změnu pořadí ... ale vyřešilo to můj problém.

Zdraví
LG
17.10.2008 04:57:00

Jakub Hejda:

Mám stejný problém, takže používám Vaše řešení.
Snad nemá Vaše řešení nějaké jiné skryté vady :-)
22.6.2009 10:16:47

ikona Qwerty:

Já jsem měl ten stejný problém a vyřešil jsem ho prostě IFem, který zajistí použití správného pořadí na hostinzích s libiconv či glibc:

<?php
function friendly_url ($str)
    {
      setlocale(LC_CTYPE, "cs_CZ.utf-8");
      if (ICONV_IMPL=="libiconv"){
        $str = preg_replace('~[^\\pL0-9_]+~u', '-', $str);
        $str = trim($str, "-");
        $str = iconv("utf-8", "us-ascii//TRANSLIT", $str);
        $str = strtolower($str);
      }
      if(ICONV_IMPL=="glibc"){
        $str = iconv("utf-8", "us-ascii//TRANSLIT", $str);
        $str = strtolower($str);
        $str = preg_replace('~[^a-z0-9_]+~', '-', $str);
        $str = trim($str, "-");
      }
      $str = preg_replace('~[^-a-z0-9_]+~', '', $str);
      return $str;
    }
?>
30.3.2010 01:07:33

Hexim:

Trochu jsem ji zdokonalil i na prevod z win1250 :-)
<?php
function furl($nadpis) {
$url = StrTr($nadpis, "áäčďéěëíňóöřšťúůüýžÁÄČĎÉĚËÍŇÓÖŘŠŤÚŮÜÝŽ", "aacdeeeinoorstuuuyzAACDEEEINOORSTUUUYZ");
$url = preg_replace('~[^\\pL0-9_]+~u', '-', $url);
$url = trim($url, "-");
$url = iconv("utf-8", "us-ascii//TRANSLIT", $url);
$url = strtolower($url);
$url = preg_replace('~[^-a-z0-9_]+~', '', $url);
return
$url;
}
?>

29.11.2007 20:16:33

ikona Jakub Hejda:

V čem spočívá to zdokonalení ?
Na windows-1250 stačí přeci jen první řádek.
27.12.2007 10:24:19

korny:

"Přestože URL může obsahovat znaky s diakritikou (což používá např. Wikipedia), bývá zvykem ji odstranit a v URL nechat jenom písmena, čísla a oddělovač. Pro ten se nejčastěji používá pomlčka, protože podtržítko Google chápe jako spojovník (mysql_fetch_assoc bere jako jedno slovo, mysql-fetch-assoc jako tři)."

mam delej web s podtrzitkama..a nasel jsem tohle
http://www.news.com/8301-10784_3-9748779-7.html
ma to tedy nejaky vyznam..(myslim ti pomlcka NEBO podtrzitko)??
Diky za info
22.3.2008 14:46:22

TheSorrow:

Není jednodušší převést URL přímo v .htaccess ?
10.6.2008 00:18:39

ikona Jakub Vrána:

Je nesmysl pro každý nově vydaný článek nebo každý nově nabízený výrobek měnit .htaccess.
10.6.2008 13:04:54

cucací potřeby:

Inu,
převést přátelská URL na .htaccess (tedy generovat tento soubor skriptem, po každé změně a/nebo periodicky) mi přijde jako řešení:
* neelegantní,
* složitější (zbytečně),
** mimochodem, nerealizovatelné tam, kde skript nemůže vytvářet soubory v daném adresáři
* pravděpodobně s trochu větší režií,
* zřejmě i s méně pohotovou reakcí na změny,
* Pro opravdu mnoho URL (řádově tisíce a víc):
** mod_rewrite na to není stavěný (nepoužitelné)
** je možné, že bude zatěžovat (a ohrožovat) Apache jako takový
** a toto je tedy slabé místo a zneužitelné pro záměrné vytvoření velkého množství URL
* nesystémovost
** je to (zbytečně) závislé na (aktuální) verzi .htaccess
** míchají se tady dvě úrovně: skriptu a webserveru
* dost možná je to i potenciálně nebezpečné (záleží na konkrétním využití, např. přeuložením URL řetězcem obsahujícím \n bude mod_rewrite vše za odřádkováním interpretovat jako další příkaz(y)).

Jako výhody vidím:
* to, že se část výkonu deleguje na Apache (tedy jeho modul mod_rewrite) a
* to, že se při každém požadavku nemusí přistupovat k databázi (to je docela velká výhoda).

Celkově ale nevýhody převažují.
Nedokážu si představit případ, kdy by toto zůstalo jako jediné řešení. Pokud takový případ najdeš, napiš ho sem ;-)
9.1.2011 02:11:32

michal:

dnes som to chcel ísť vyriešiť sám, ale akosi sa mi nechcelo, čítal som si blogy, až som sa náhodou dostal sem. idem vyskúšať tento spôsob, dúfam, že bude fungovať.
7.10.2008 05:34:26

Gifi:

Dobrý den, již pár dní špekuluji nad jistým problémem. Ani kamarad google mě nedokazal poradit, tak tedy prosím o radu ostřílených vývojářu.

Problém je následující:
mam index.php v documentroot kde pouzivam dotaz kde si pri kazdem vygenerovani banneru provadim dotaz Update tabulka set zobrazeno=zobrazeno+1 where id_vygenerovaneho baneru...s tím by nebyl až takový problém. dotaz a vše kolem funguje.
problém nastává při použití mod_rewrite. kdyz obnovím stránku pri vygenerovani se přičte dva namisto jedna, když jdu na index.php ve složce admin přičte se opět dva... Kdyz vypnu modrewrite tak uz se v adminu nic nepricita. z toho všeho jsme nabil dojmu, kdykoliv volam index.php jak v rootu tak v podadresari admin tak to vzdy projde pres index.php v rotooo.  neslo by zase tak o to pricinani,ale docela si myslim ze to spomaluje cely server dost vyrazne,protoze se nejdrive provedou skrypty z index.php root a pak teprv v adminovi, pokud v adminovi pracuji.

pro ukazku modrewrite:

RewriteEngine On

RewriteCond %{HTTP_HOST} ^tvorime\-web\.cz
RewriteRule ^(.*)$ http://www.tvorime-web.cz/$1 [R=301,QSA]

RewriteCond %{REQUEST_URI} .admin.*
RewriteBase /admin
RewriteRule ^(.*)$ - [L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?url=$1 [L,QSA]

Zatím sem se s ničím takovým nesetkal po dvou letech co s phpckem delám..
5.11.2008 01:38:43

Jan Mička:

Dnes jsme přešli na verzi PHP 5.2.7 a vaše funkce přestala fungovat... Nedokázal byste poradit prosím?

Warning: preg_replace() [function.preg-replace]: Compilation failed: unknown property name after \P or \p at offset 4

PHP: 5.2.7.
PCRE Library Version: 7.8 2008-09-05
6.12.2008 00:49:44

ikona Jakub Vrána:

Mě to v PHP 5.2.7 funguje. Máte PCRE knihovnu zkompilovanou s podporou UTF-8? Nevím bohužel, jak se to dá zjistit. Slouží k tomu nicméně volba --enable-utf8 při kompilaci pcrelib.
6.12.2008 03:48:15

Jan Mička:

No, ale ve verzi predtim to fungovalo i tak jak to bylo - PCRE knihovna se nemenila, jen PHP.
6.12.2008 10:43:33

Jan Mička:

PCRE je kompilovano jako --enable-utf8 --enable-unicode-properties ... takze kde jinde by mohla byt chyba?
6.12.2008 10:46:43

Michal Orlik:

Mel jsem stejny problem s verzi 7.8...po downgradu vse ok
6.12.2008 11:46:23

btx:

stacilo po upgradu na libpcre-7.8 prekompilovat PHP a problem byl pryc (pouzivam gentoo)
1.1.2009 05:44:37

ikona Karel Dytrych:

Zkuste třeba toto:

<?php
function tourl ($str)
{
  setlocale(LC_CTYPE, "cs_CZ.utf-8");
  $str = iconv("utf-8", "us-ascii//TRANSLIT", $str);
  $str = preg_replace("~[^\w\d]+~", '-', strtolower($str));
  $str = trim($str, "-");
  $str = preg_replace('~[^-\w\d]+~', '', $str);
  return $str;
}
?>

6.12.2008 02:13:04

pojízdná kočka:

chtěla bych se podělit o praktickou zkušenost s "přátelským URL" (pro návštěvníka stránek - ne zas tak přátelské pro programátora).

Komplikace začínají, pokud si správce stránek může URL zvolit (nabídli jsme tu možnost jednomu našemu klientovi) a on ji několikrát využil (některé zboží, které prodává, má lomítko ve svém názvu). V ten moment při načtení stránky zmizely všechny obrázky a stránka se zobrazila bez stylů, nefungovaly externí skripty atd. (Důvod: další lomítka zkonstruovala dodatečné 'virtuální adresáře'.) Jedna cesta by bylo odkazovat všechny zdroje v HTML absolutně, ale to jsem vyhodnotila jako jako špatné řešení, protože např. se změnou domény by na x místech najednou vznikly chybné odkazy.

Jako řešení mě tedy napadlo na začátku skriptu zanalyzovat $_SERVER["REQUEST_URI"], zjistit počet lomítek a tolikrát přidat za sebe řetězec "../", který pak vkládám před každý odkaz (href u <a>, src u <img>, atd) v HTML. Antagonicky k tomu, php funkce pro práci se soubory se samozřejmě 'adresáři', které vznikly přidáním lomítka do adresy, "zblbnout" nenechají (resp. takto vzniklé pseudo-adresáře jsou vůči jejich práci irelevantní).

(snad to pomůže těm, co s tím zrovna zápasí ;-))
8.2.2009 22:54:47

ikona Karel Dytrych:

Adresy ještě můžete psát ve tvaru /cesta/s-lomitky.html ... Odkaz je poté absolutní a nezávislý na doméně.
9.2.2009 00:28:38

ikona david@grudl.com:

Naopak bych velmi doporučil používat vždy a bez výjimky všechny odkazy absolutní. Vtip je ale v tom, že kromě absolutního URL existuje ještě absolutní cesta. Tedy odkaz bez uvedení domény začínající lomítkem. Takže stačí href="/css/style.css" a je jedno, na jakém místě se stránka nachází.
9.2.2009 08:02:23

pojízdná kočka:

a když klient řekne "ty současné stránky hoďte do adresáře 'old'"? V ten moment se historie opakuje a pak bych opět musela projít celý projekt a na desítkách až stovkách místech nahrazovat dopisovat před absolutní cestu tento adresář. To je jeden příklad ze tří (aneb pozor, ještě jsem neskončila ;)). Ten druhý je případ, kdy nějaký projekt, co normálně bude na /index.php testuju a mám (u sebe, na localhostu) na /projekt001/index.php (neboť podobných projektů dělám hafo, i více najednou a ne každý může mít to privilegium být na kořeni). Třetí případ, který mě napadá, je shodou okolností na Jakubových stránkách - a sice možnost stažení webu jako archiv html stránek. Když si je někdo stáhne a rozbalí do nějakého adresáře, např. do /resources/jakub_vrana/*.* , tak by asi též nebyl potěšena, že styly nefungují, protože se tahají ze souboru /css/style.css, kterýžto neexistuje.
Jinými slovy, moc jste mě, pánové, nepřesvědčili ;-)
12.2.2009 21:21:45

ikona Karel Dytrych:

A co vam brani provozovat u sebe na "localhostu" vice virtualnich serveru? http://projekt1/, http://projekt2/ apod.? Take ty soucasne stranky muzete hodit treba na subdomenu old... ne?
13.2.2009 04:48:33

ikona david@grudl.com:

To se nestává :-)) Stará URL se přece zachovávají.

Ale dobře, zůstaňme u relativních adres. Jak vyřešíte, tento výpadek kaskádových stylů? http://hovnovbotach.wz.cz/index2.php/ahoj/
13.2.2009 06:42:53

ikona Jakub Vrána:

To by v první řadě mělo skončit 404. V daném případě by stačilo vypnout AcceptPathInfo.
15.2.2009 03:00:05

Ich:

No, páč u toho nepřemýšlíš...
1) proste v mod_rewrite nastavíš, že když je v ceste /old/, tak se css, img a další, dle potřeby, přepíše na /neco_kde_mam_old/img/ - a podobně. A máš po starostech...
2) stačí si na localhostu pořádně nainstalovat server, tedy i s virtuál-hostama, pak neřešíš problémy typu "nám to nejdede, protože jsme to tesovali na localhost a tam se to chovalo uplně jinak než na produkčním serveru"
3) když dám možnost stahovat na lokál (skoro)celý web, tak buď pro generování archivu vytvořím pravidlo, nebo napíšu návod, jak "nainstalovat" lokální kopii tak, aby fungovala... (tj. nakopírovat css adresář na root disku, odkud prohlížím archiv..

Prostě jen u toho trošičku přemýšlet a ono to už půjde samo.
13.2.2009 07:49:03

ikona Jakub Vrána:

1. Když odkazy vedou na /css/, tak /old/ v cestě není.

3. Opravdu se nedá označit za unobtrusive řešení říkat někomu, ať si zasere root disku.

Než někomu začneš říkat, že nepřemýšlí, měl bys přemýšlet sám.
15.2.2009 03:08:38

pojízdná kočka:

2. OK, uznávám (pro úplnost)
28.2.2009 08:14:32

Franta:

Zdravim, s USER FRIENDLY URI se peru teprve par dni... pekny clanek... ale unika mi co s vysledkem, ktery FCE vyhodi? Kam s nim, aby to zmenilo URL? Diky L.
16.2.2009 05:22:44

pojízdná kočka:

Zaprvé - toto řešení je pro dynamické weby, které mají předem neznámý počet (někdy stovky až tisíce) samostatných stránek (detailních stránek produktů u e-shopů, článků u zpravodajských serverů apod.).

Ta funkce představuje způsob, jak každé této stránce automaticky (strojově) přidělit část URL za doménou, kterou má být skript později schopen najít. Předpokládá se, že se název URL odvíjí od názvu dané stránky, který je někde uložen (typicky v databázi).

Při ukládání záznamu stránky se dá uložit i takto upravená URL; při (jak to říct?) "lokalizaci" stránky na serveru mod_rewrite přesměruje požadavek na defaultní skript (typicky index.php), který si stránku už umí najít (databázovým dotazem na stránku, jejíž pole určené pro uložení této části URL se shoduje s tím, co je v $_SERVER['REQUEST_URI']).
17.2.2009 04:06:47

Franta:

děkuji za odpověď, hlavně bod ZAPRVÉ je skvělý ;-) ale jen jsem chtěl vědět, jak dál použít upravený řetězec (přívětivé URL) v praxi. Upravit string, je myslím na celé problematice to nejjednodušší... F.
17.2.2009 15:03:11

blizz.boz:

http://ipremiere.eu/davov%C3%A1-psych%C3%…-adresy.html
29.5.2009 09:11:33

pojízdná kočka:

Zajímalo by mě, jestli by se funkce jako make_url() dala udělat přímo v prostředí databáze jako databázová funkce..
4.9.2009 00:59:19

ikona Jakub Vrána:

Na Daily WTF jsem kdysi viděl funkci, která funkci REPLACE() volala asi 15x zanořenou. Sloužila pro vyhledávání v dlouhých textech bez diakritiky, na což se opravdu moc nehodila, ale na krátký řetězec by to nijak zvlášť nevadilo (když pominu obludnost kódu).
4.9.2009 01:08:38

pojízdná kočka:

Teprve teď jsem se k tomu dostal.
http://thedailywtf.com/gsearchresults.aspx?…=Search#1033
Ale odradil mě název rubriky - Stupid Coding Tricks ;-)
9.2.2010 22:31:11

Václav Vaník:

A co třeba http://pecl.php.net/package/translit ?
31.10.2009 13:16:25

ikona v6ak:

Nebo webalize v Nette.
1.11.2009 10:34:41

cucací potřeby:

to by mělo být principiálně to samé jako tady
9.1.2011 01:38:50

Alex:

Dekuji. Hledal jsem na podobnu funkce.
Diakritika porovano lehko dala se transliterovat.
Azbuka musi byt s strstr.
1.11.2009 09:14:18

majo:

jj staci jedno pismenko azbuky a cely prevod zlyhava :(
23.1.2010 12:11:44

pojízdná kočka:

Na Intervalu vyšlo takové kolokvium "předních expertů na SEO"

http://interval.cz/clanky/google-search-engine-…-url-stranky

a v jeho závěru se došlo k tomu, že "relevance na klíčová slova" představuje pro Google cca 9 % ze 100.
Z těchto 9 % "přátelské URL" podle mého skromného odhadu mohou zabírat takových 5 % (tedy 5 % z vnitřních faktorů).
Z výše uvedeného vyplývá, že čisté URL mají vliv 0,09 * 0,05 = 0,0045 - tedy 4,5 promile na optimalizaci pro vyhledávače.
Prvek z vnitřních faktorů, který má asi největší význam, je <titile>. Nezřídka je ale vidět weby s přátelským URL a titulky "NONAME001.HTM", "Untitled". To je čistá dmnc, ale toť už jiná kapitola...
13.2.2010 22:54:07

Otto:

Funkce je fajn.

Jak ale řešit v .htaccess výstup ze search form (search engine) s get parametrem, když napíšu ŠKODA? Jak naladit, aby ve výstupu při přesměrování zůstala česká diakritika a nikoliv procenta a přehozený nesmysle místo českých znaků? Těžko vnutím nějakou funkci PHP při předávání get parametrem do URI :-P
Prolezl jsem za poslední dva tři dny mraky zdrojů a nikde nic.

Tady přikládám to vlastní přesměrování.

RewriteCond %{QUERY_STRING} ^string=(.*)
RewriteRule ^search\.php /hledani/%1.html? [R=301,L,E]

RewriteRule ^hledani/(.*)\.html$   search.php?adv_text=$1   [QSA]

23.9.2010 00:42:21

ikona Jakub Vrána:

Přesměrování může provést přímo PHP skript, nemusí to dělat mod_rewrite.
23.9.2010 07:40:15

Otto:

Jakube, děkuji za radu. Jakmile to vyřeším, pošlu to sem.

O.
23.9.2010 13:04:28

Otto:

Přes Htaccess nebo v nastavení Apache.
23.9.2010 13:04:57

Holmistr:

Jestli jsem pochopil problém správně, tak ti vadí to, že do adresy zadáš skript.php?promena=škoda a v proměnné (např.) $_SERVER['QUERY_STRING'] máš ahoj=%9Akoda.

Řešení bych měl jednoduché. Prohnat $_SERVER['QUERY_STRING'] funkci urldecode().

Opravte mne prosím, pokud se mýlím :-)
25.9.2010 20:38:43

Pur:

Zdravím, potřeboval bych poradit.
Používám Mod_rewrite pro generování přátelských URL:

RewriteRule ^(.*)/$ index.php?rw=1&stranky=%{REQUEST_URI} [R=301,L]

Do proměnné "stranky" se mi načte vlastně cesta na webu s lomítky, v PHP si z ní udělám pole a čtu z něj. Bohužel si zatím moc nerozumím s regulárními výrazy a nedaří se mi provést následující: pokud bych měl adresu v prohlížeči
www.example.com/uroven1/uroven2/, vše je v pořádku a do proměnné "stranky" se mi načtou úrovně. Ale chtěl bych upravit pravidlo přesměrování, abych mohl použít například také url
www.example.com/uroven1/uroven2/?hledat=hledany_text

Nevím si s tím rady :-(
2.1.2011 16:41:55

Pur:

mám to, stačí příznak QSA :)
2.1.2011 17:21:08

Ján Žitniak:

Chcem sa opýtať - keď si vygenerujem pomocou Tvoje funkcie friendly_url() priateľskú adresu, napr. v tvare najlepsia-fotka-na-slovensku tak ako tom mám na strane kódu ošetriť, aby k URL bol priradený konkrétny obsah?

Jedná sa mi o to, že niekto zadá www.mojaadresa.sk/najlepsia-fotka-na-slovensku a teraz ku akému skriptu to bude priradené? Cez .htaccess by som to riešil cez RewriteRule v PHP si to viem predstaviť, že bude mať pole, kde sa budú priateľské url odkazovať na skutočné url, je to tak správne?
18.1.2011 09:42:44

Tomáš Vojtášek:

V PHP 5.3.1 mi hlásí:
iconv(): Detected an illegal character in input string
9.3.2011 22:19:47

Dano:

Zdravim, super vec...ale napr. ked to pouzijem na premenovanie suborov, aby neobsahovalidiakritiku a podobne znaky, odstrany to aj priponu, je to mozne nejako osetrit? aby nezmizla bodka pred priponou? Súbor.jpg zmeni na suborjpg :((
28.7.2011 10:09:30

Morellato:

Řekl bych, že udělat hezké URL byl správný krok, je fajn, že už je to tak dlouho. A je zpětně zábavné pozorovat dřívější reakce některých odborníků:)
8.12.2011 19:11:52

Šimon:

Jsem velký amatér, ale když prohlížím příklady stránek na netu,
a vidím http://example.com/silenynazev.php?jestesilenej…=123925876249 tak si řeknu že je pro mě příjemnější /skripty/pocitadlo/.
Ale mnozí si toho podle mě dnes už nevšimnou protože je zajímá jen obsah stránek né adresa, a že když se na ni chtějí vrátit mají Windowsowskou schránku nebo prohlížečové záložky,
a o víc se nestarají, pokud to tedy vysloveně nejsou odborníci na zapamatovatelnost URL... Mě je to při prohlížení upřímně jedno, hlavně když najdu co očekávám, nebo hledám.
15.1.2012 11:03:38

Kuba:

Dobrý den, mám dotaz, co když při vytváření článku narazím na článek, který má úplně stejný název jako článek, který je již v DB, jakým způsobem byste toto ošetřil? Díky.
6.6.2012 13:14:24

ikona Jakub Vrána:

Obvykle se to řeší přidání nějaké přípony – pořadového čísla nebo datumu.
7.6.2012 17:23:34

blicí punčocháče:

A anglická Wikipedie dělá rozcestníky (disambiguation pages) s odkazy na všechny relevantní odkazy. Ale to je trochu jiný případ. Články o něčem, co se jmenuje stejně, pak rozliší upřesněním v závorce (s tím, že konverzi nedělá). Např.:
Genius (mythology)
Genius (literature)
Genius (2016 film)
Genius (2018 Hindi film)
Genius (2018 Tamil film)
...
9.3.2019 17:46:30

VelbloudiNotace:

Dobrý den. Jsem úplný začátečník, a tak vůbec nevím jak to použít. Napadlo mě že bych ten kód vložil na začátek stránky, ale nejsem si tím jist. Jestli to chápu špatně, tak prosím o nějaký příklad.
23.3.2013 00:22:38

J.:

Když obchodnímu partnerovi pošlu odkaz na www.neco.cz/cenik, tak to má rozhodně větší úspěsnost než www.neco.cz/?page=5

Rozdíl asi jako mezi profi vytištěnou vizitkou a vizitkou vytištěnou na ušmudlaný kancelářský papír?
2.5.2013 12:30:47

M:

Tak "á" se mi určitě nepřevádí na "a", vynechá to. Zkusím něco jiného. :)
16.6.2013 13:53:29

v6ak:

Já bych řekl, že to funguje:

[6] boris> friendly_url(file_get_contents("php://stdin"));
řčžčřžščžčřžýéíáýžřčšě+áx
→ string(25) "rczcrzsczcrzyeiayzrcse-ax"

Používáš tu funkci přesně tak, jak je zde uvedena?
16.6.2013 14:12:49

tom:

Zdravim, zacnu klasickou informaci, ze jsem prolezl vazne vsechny mozny weby a klicovy slova, abych nasel reseni, ale nic mi nefunguje, patrne to bude blbost nejaka. K veci. snazim se o krasny url.

Vzor
RewriteRule ^page/([^/\.]+)/?$ index.php?page=$1 [L]

at uz v nem prepisuji a nazyvam cokoli jakkoli, mi nefunguje

Nejde mi ani zprovoznit to co jste popisoval na zacatku tohoto tematu.

Muj pripad je klasicky:
http://www.example.com/clanek?clanek_id=1
chtel bych
http://www.example.com/1-nadpis-clanku

RewriteRule ^stranka/?$ /index.php?page=stranka [L,QSA]
normalne funguje, vyznam [L] atd chapu.

Dekuji kazde dobre dusi, ktera by me navedla spravnym smerem.
Tom
12.5.2015 13:12:34

chcací šuplík:

Má někdo tipy na to, jak se nejlépe vypořádat se změnou názvu článku (ať už z jakéhokoli důvodu) poté, co k němu byla přiřazena/zkonvertována url a byl prolinkován? Díky
9.3.2019 17:48:25

ikona Jakub Vrána:

Přiřadit nové URL a staré na něj přesměrovat.
21.3.2019 08:52:19
avatar © 2005-2024 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.