Archiv rubriky: Tutorials

Jak nastavit čtečku čárových kódů?

Čtečka čárových kódů. Je snad úplně všude a jestli ne, tak svět je jedna velká čtečka :)

Když máme připravený nějaký vstup, do kterého chceme načítat data z čtečky, zapojíme tu mrchu a ona nefunguje. Nebude fungovat. Nejdříve to asi 159x zkusíte, pak si přečtete anglický manuál, kterému rozumíte jak koza petrželi. Pak přijde na řadu Google. A tak jste se dostali až sem :)

Jak taková čtečka funguje?

Je to hloupá simulace klikání do klávesnice. Čárový kód v sobě nese nějaká data, většinou ASCII a hlavně číslice. Čtečka to, co vidí, nakliká na klávesnici a tak vznikne vstup. Místo vašeho 0004358 dostáváte ÉÉÉČŠŘÁ a asi vás raní mrtvice.

Jednoduchá rada

V nastavení hlavního jazyka klávesnice ve vašem OS nastavte angličtinu. Jak jednoduché, co? :)

Pozn. Některé čtečky umí pracovat s českou klávesnicí, ale je třeba nakonfigurovat čtečku dle manuálu.

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 :)

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.

Řazení dvourozměrného pole v PHP

Čas od času se přihodí, že je třeba seřadit dvourozměrné pole. Můžeme si na to napsat vlastní funkci a nebo použít funkci array_multisort, kterou disponuje samotný jazyk.

1. mějme pole

$pole = array(
 array('id' => 2, 'nazev' => 'Okurka'),
 array('id' => 15, 'nazev' => 'Jablko'),
 array('id' => 8, 'nazev' => 'Texas')
 );

2. vytvořme data pro řazení

$data = array();
foreach ($pole as $hodnota)
{
  $data[] = $hodnota['id'];
}

3. seřaďme původní pole

array_multisort($data, $pole);

Výsledkem je seřazené původní pole. Celé to funguje na jednoduchém principu, kdy si připravíme data, která jdou programově lehce seřadit a podle nich se pak seřadí naše dvourozměrné pole.