Monthly Archives: Srpen 2013

Jak na více než 9 zpětných referencí v .htaccess?

Dnešní článek není pro širokou veřejnost, ale spíše pro úzkou skupinu vývojářů, kteří hledají, proč jim nefunguje .htaccess správně. Zpětných odkazů lze použít pouze 9, tak to prostě je a s tím nic neuděláte.

Co jsou zpětné reference?

Jak jsem na začátku podotknul, k řešenému problému se nedostane začátečník, tudíž jen ve zkratce. Chceme-li efektivně přenášet data z hezkých SEO URL k našim scriptům, využijeme např. následující pravidlo přepisu (RewriteRule).


RewriteRule  ^([a-z]{1})(\d+)-([a-zA-Z0-9_\-]*).html$
   /index.php?katalog&druh[]=$1&id[]=$2&jmeno[]=$3 [L,QSA]

Takové pravidlo nám přenese adresu /z1-barum.html na index.php?katalog&druh[]=z&id[]=1&jmeno[]=barum. Ve scriptu tedy můžeme přistupovat rovnou k proměnným $_GET[‚druh‘] atd. Každá množina regulárního výrazu z první části pravidla lze vyjádřit tzv. zpětnou referencí = ([a-z]{1}) ~ $1 . Řešení je to velice efektivní a dá se říci nejrychlejší pro server.

A kde je háček?

Háček nastane v okamžiku, kdy si váš šéf umane, že mu nestačí  /z1-barum.html, ani /z1-barum/v1-13palcu.html a ani /z1-barum/v1-13palcu/d1-zimni.html. Pravidlo pro přepis samozřejmě rozšíříte o další /^([a-z]{1})(\…, ale počítejte se mnou:

backref

9. To je konečné číslo. Dál se prostě nikdy nedostanete, jelikož Apache jich více nezvládne, ani když se rozkrájíte.

V okamžiku, kdy teprve navrhujete řešení, to problém být nemusí, zvolíte jiný návrh schéma URL. Problém nastává, když máte předělávat již zaběhlý e-shop s kompletním řešením postaveném na globálních proměnných z URL ze zpětných referencí.

Proč vůbec?

Důvod je prostý, chceme před koncovku .html dostat co nejvíce klíčových slov pro vyhledávače. Další argument můžeme nacpat do .html?vozidlo=2, ale je více než pravděpodobné, že taková stránka nebude dostatečně naindexovaná, jelikož hledače často tyto argumenty přehlížejí.

Co stím?

Z .htaccess se budeme muset přesunout níže – do parsování v jazce, v našem případě PHP. Řešení je to sice již pomalejší, ale více zpětných referencí nevyrobíme.

Nejdříve si upravíme .htaccess. První možnost pro /z1-barum.html zanecháme, jelikož bychom ztratili význam ostatních pravidel, nechceme přeci (cokoliv).html směrovat do katalogu produktů.


RewriteRule  ^([a-z]{1})(\d+)-([a-zA-Z0-9_\-]*).html$
    /index.php?katalog&druh[]=$1&id[]=$2&jmeno[]=$3 [L,QSA]

RewriteRule  ^([a-zA-Z0-9_\-]*)/([a-zA-Z0-9_\-]*).html$
    /index.php?katalog&data[]=$1&data[]=$2 [L,QSA]

Zápis se nám značně zjednodušil, nyní přenášíme celé ‚z1-barum‘ a ‚v1-13palcu‘ v poli data[]. Postupně zavedme další řádky, které mají více a více /([a-zA-Z0-9_\-]*). Samozřejmě i to má omezení – přeneseme tak opět 9 referencí, ale to nám snad už bude stačit – /xx/xx/xx/xx/xx/xx/xx/xx/xx.html. Pokud ne, musíme parsovat celou adresu až ve scriptu.

Teď už jen musíme PHP doplnit parserem, který rozseká získaná data, jelikož jsme přišli o &druh, &id i &jmeno.

//zavedeme globální proměnné, jelikož je nezískáváme přímo z URL
if(!isset($_GET['druh']))
{
  $_GET['druh'] = array();
}
if(!isset($_GET['id']))
{
  $_GET['id'] = array();
}
if(!isset($_GET['jmeno']))
{
  $_GET['jmeno'] = array();
}

//Projdeme $_GET['data'] a pokud odpovídají \x1-xxx,
//předáme je do proměnných jako by se nechumelilo
if(isset($_GET['data']) && is_array($_GET['data']))
{
  foreach ($_GET['data'] as $pravidlo)
  {
    if(preg_match('/([a-z]{1})(\d+)-([a-zA-Z0-9_\-]*)/', $pravidlo))
    {
      $_GET['druh'][] = substr($pravidlo, 0, 1);
      $_GET['id'][] = substr($pravidlo, 1, strpos($pravidlo, '-')-1);
      $_GET['jmeno'][] = substr($pravidlo, strpos($pravidlo, '-')+1, strlen($pravidlo));
    }
  }
}

Závěrem

Již při návrhu URL je důležité přemýšlet nad celým schématem a jeho rozšiřitelností. Je zde hezky vidět, že jinak může přemýšlet majitel, manažer, SEO guru i programátor. Pak se to celé musí překopávat a nebo v našem případě hezky záplatovat :)

E-Business FORUM 2013 v SaSaZu

Pražský klub SaSaZu známý spíše díky koncertům se 29. září promění v dějiště E-Business FORUM 2013, které pořádá APEK (Asociace pro elektronickou komerci) a  TUESDAY Business Network.

Již popáté se můžete zúčastnit konference věnované elektronické komerci. V pražských Holešovicích vystoupí např. Ondřej Fryc (Netretail Holding, zakladatel Mall.cz) nebo John Vanhara, zakladatel služby Shipito.

Konečná cena pro vstup je 5 989 Kč včetně DPH.

Na programu je mnoho tuzemských i zahraničních hostů. Pokud se tedy chcete dozvědět jak zefektivnit vaše podnikání na internetu, nenechte si akci ujít. Já už jsem registrovaný.

—–

E-Business FORUM 2013

Atomatický perex v PHP

Nedávno jsem narazil na zásadní problém. Nechat vyplňovat redaktory samotnou část pro perex nebo perex generovat automaticky. Zvítězila možnost generovat prvních několik řádků článku automaticky. Ale jak na to?

1. problém

Největším naším problémem je, že redaktor formátuje text v nějakém editoru a tudíž náš získaný text může být jakýkoliv HTML kód. Na internetu nalezneme šikovné funkce, které umějí „uříznout“ řetězec a zohlednit právě HTML značky. To nám však nepomůže v problematice, kde a jak navázat text za perexem (zbytek článku).

2. nalezení ideálního místa pro ukončení perexu

Nejdříve si stanovíme, kde náš perex bude končit, v našem případě po 300 znacích. Poté nalezneme konec slova nebo věty, abychom perex neuřízli uprostřed slova. K tomu použijeme rekurzivní funkci  najitkonecslova(). Ke konci slova přičteme +1 pro přeskočení nalezeného konce (mezery).


function najitkonecslova($retezec, $offset)
{
 // if($retezec[$offset] != '.') pro konec věty
 if($retezec[$offset] != ' ')
 $offset = najitkonecslova($retezec, $offset+1);

 return $offset;
}

$konec_perexu = najitkonecslova($clanek['obsah'], 300)+1;

3. řezání

Jednou měř a třikrát řež, beztak to posereš… Ořez znaků v UTF-8 je obecně docela vtipná záležitost v PHP5. Pokud chceme použít funkci substring(), s největší pravděpodobností se nám to nepovedle dle představ. Návodů nalezneme hromadu, já použil řešení od mého kamaráda Adama Bohunčáka využívající nesmyslné (avšak funkční) konverze z UTF-8 do UTF-8.

function my_substr($str, $start, $length)
{
 return mb_substr(iconv('utf-8', 'utf-8', $str),
  $start, $length, 'utf-8');
}

3. Učesání

Perex by měl být text bez speciálního formátování, ideálně naznačen kurzívou. Redaktorovi ale těžko vysvětlíte, že během prvních 300 znaků se má vyvarovat tučnému písmu, nadpisům apod. Vyřízneme tedy perex pomocí funkce my_substr a perex zbavíme všeho formátování, k tomu slouží php funkce strip_tags.

$perex = strip_tags(my_substr($clanek['obsah'], 0,
 $konec_perexu));

4. Výpis

Získali jsme tak perex – čistý text bez formátování. Abychom zachovali validitu i styly stránky, uzavřepe perex do odstavce <p>, můžeme přidat i nějaký styl, kterým dodefinujeme např. zmíněnou kurzívu apod. Počítáme tedy s tím, že původní text z redaktorova editoru je ve struktuře <p> … </p>. Na závěr vypíšeme zbylý, již formátovaný obsah článku za použití opět my_substr se začátkem od konce prerexu.

echo '<p>'.$perex.'</p>';
echo '<p>'.my_substr($clanek['obsah'], $konec_perexu,
 (strlen($clanek['obsah']))-$konec_perexu);

Pokud praxe ukáže, že řešení má své mouchy, určitě článek aktualizuji.