Jak jsem přešel na linux.

na 3.7.2010, in Tak různě..., u admin

Už dlouho sem se odhodlával k přechodu z Windows 7 (měl jsem je jako OEM k noťasu v nějaké Home verzi) na Linux. Před dvěma roky jsem na Linuxu pracoval a celkem se mi to líbilo, ale pak jsem zase přešel zpátky na Windows. Nyní už jedu zase týden na Ubuntu a jsem spokojený.  Když se mi začali najednou nesmyslně Windows bortit a říkal jsem si, že je asi čas na formátování disku, tak jsem si vzpomněl, že bych mohl při té příležitosti přičuchnout k tučňákovi.

Přechod byl hodně impulzivní. V podstatě jsem si řekl TEĎ, všechno zálohoval na externí disk a zformátoval disky. Instalace proběhla velice hladce a rychle. Velice příjemně mě překvapilo, že nebyl problém s žádným HW a hodně rychle jsem našel alternativy k mým oblíbeným programům. Nádherná je komunikace, kterou má ubuntu přímo v sobě. (emaily, IM…) Dalším šokem bylo, že má multimediální klávesnice funguje i na linuxu. Jen jsem zmáčkl ze zvyku stop a ono to fakt zastavilo přehrávač :-)

Zatím sem měl jen drobný problém s FTP, ale naučil jsem se mount přes curlftpfs a funguje to hezky. Ještě musím přijít na to, jak zařídit, aby se při odpojení externího monitoru nastavil ntb jako primární monitor…

 

Před nějakou dobou jsem potřeboval vytvořit efektivní fulltextové vyhledávání ve velké DB. Sice se informace dají najít, ale zkusím to trošku shrnout.

Představte si, že máte tabulku `tabulka` v MySQL DB.

ID | NAZEV | POPISEK | KATEGORIE

Tato tabulka má statisíce záznamů. Nenapadlo mě nic lepšího než využít fulltextu přímo na úrovni DB. MySQL umožňuje si vytvořit fulltext indexy a podle nich hledat.

CREATE FULLTEXT INDEX ON tabulka(nazev, popisek, kategorie) KEY INDEX fulltext;
CREATE FULLTEXT INDEX ON tabulka(nazev) KEY INDEX fulltext_n;
CREATE FULLTEXT INDEX ON tabulka(popisek) KEY INDEX fulltext_p;
CREATE FULLTEXT INDEX ON tabulka(kategorie) KEY INDEX fulltext_k;

Možná se někomu zdá divné, že jich je třeba vytvořit tolik, ale je to logické. První index pracuje se všemi třemi sloupci a bude nám dávat všechny výsledky. Další 3 indexy budou sloužit k vylazení relevance.

Nyní chceme z DB vybrat všechny výsledky, které obsahují slovo ‘pauza’ a zároveň řadit podle relevance.

SELECT * FROM tabulka WHERE MATCH(nazev, popisek, kategorie) AGAINST('pauza je dlouhá');

Toto by bylo výborné, ale… Nefunguje pro části slov. Klíčové slovo musí mít více než 4 znaky a neberou se v potaz slova, která jsou ve více než 50% záznamů. Navíc se používají stopwords, která se dají nastavit i česká, ale toto mě až tak netrápilo. Nejhorší byla absence hledání podle částí slov. Toto umí boolean mode. Pokud bychom dali MATCH AGAINST do selectu, tak bychom viděli desetinné číslo od 0 do 1, které vyjadřuje relevanci.

SELECT * FROM tabulka WHERE MATCH(nazev, popisek, kategorie) AGAINST('*pauza* *je* *dlouhá*' IN BOOLEAN MODE);

Stopwords se sice stále využívají a stále platí minimální počet znaků (dá se přenastavit v ini souboru mysql) – proto by se „je“ mělo filtrovat už v php, ale pro názornost jsem to tam uvedl. Nicméně už se dají používat asterisky pro části slov. Existuje více takových klíčových znaků. Kompletní výpis zde.

Problémem je, že releavance už je vyjádřena jen jako 1 nebo 0, proto si musíme trochu pomoci.

SELECT * FROM tabulka
WHERE MATCH(nazev, popisek, kategorie) AGAINST('*pauza* *je* *dlouhá*' IN BOOLEAN MODE)
ORDER BY 10 * MATCH(nazev) AGAINST('*pauza* *je* *dlouhá*' IN BOOLEAN MODE)
       + 5 * MATCH(kategorie) AGAINST('*pauza* *je* *dlouhá*' IN BOOLEAN MODE)
       + 1 * MATCH(popisek) AGAINST('*pauza* *je* *dlouhá*' IN BOOLEAN MODE)
;

Nyní vidíme, že pokud je v názvu část těchto slov dostanou 10*, pokud v kategorii tak 5*, pokud v popisku tak 1*. Bylo by odeální v ORDER BY používat MATCH AGAINST bez BOOLEAN MODE, ale potřeboval jsem vyhledávání v částech slov, proto se toto zdá jako nejlepší řešení.

 

Odesílání emailu

na 11.6.2010, in Frameworky, u admin

Seriál k Zend Frameworku začnu velice jednoduchým příkladem. Je to velice hezké zapouzdření odesílání emailu přes PHPMailer a příp. i přes SMTP.

require_once ''Zend/Mail.php';
$mail = new Zend_Mail("UTF-8"); //zajistí správné kódování českých znaků
$mail->setBodyText('Mail jako plaintext'); //dobré pro některé exotické emailové klienty a pro rychlé náhledy
$mail->setBodyHtml('Mail jako HTML.');
$mail->setFrom('odesilatel@odesilatel.com', 'Jméno Odesílatele');
$mail->addTo('prijemce@prijemce.com', 'Jméno příjemce');
$mail->setSubject('Předmět');
$mail->send(); //odešle email
  1. $mail = new Zend_Mail();
  2. $mail->setBodyText(‘This is the text of the mail.’);
  3. $mail->setFrom(’somebody@example.com’, ‘Some Sender’);
  4. $mail->addTo(’somebody_else@example.com’, ‘Some Recipient’);
  5. $mail->setSubject(‘TestSubject’);
  6. $mail->send()
 

Svůj cyklus návodů začnu elegantním řešením načítáním velkých XML souborů.

Před několika týdny jsem se dostal do situace, kdy jsem potřeboval velice rychle zpracovat obrovské XML (80 MB) na standartním hostingu s časovým limitem 120s a paměťovým limitem 128 MB. Po chvilkovém zápolení a hledání jsem nalezl řešení.

$reader = new XMLReader();
$reader->open('obrovske.xml');

while ($reader->read()) {
  switch ($reader->nodeType) {
    case (XMLREADER::ELEMENT):
    if ($reader->localName == "jmeno_elementu_ktery_chceme") {
      $node = $reader->expand();
      $dom = new DomDocument();
      $n = $dom->importNode($node,true);
      $dom->appendChild($n);
      $v = simplexml_import_dom($n);
    }
    break;
  }
}

Jak je vidět z této ukázky, tak myšlenkově postupuji takto. XMLReader je velmi rychlý i pro velké soubory – nepotřebuje si nejdřív soubor rozparsovat,  ale jde postupně. Takže si taháme jen ty nejmenší elementy, které potřebujeme a ty „nacpeme“ do DomDocument a poté do simplexml. (je samozřejmě možné úplně vynechat simplexml a rovnou tahat data z DomDocument, ale mně se líbí více tento způsob – je také velice rychlý a přitom nabízí opravdu snadnou práci s daty). Dále už s tím pracujeme jako s objektem simplexml, který se hezky rozparsuje celý, ale protože je malinký, tak je to fofr.

Snad se vám bude mé řešení líbit a možná i někomu pomůže.

 

Začínáme

na 5.6.2010, in Tak různě..., u admin

Po dlouhé době si můžu říct, že nejsem v časové tísni. Nic nemusí být do zítra hotové. Dokonce jsem se zase začal aktivně koukat po poptávkách,

Splním si své plány z minulého roku. Chtěl jsem si udělat web, kde si budu budovat nějaký svůj brand, zapisovat si své programátorské objevy, tak abych je vždy našel a aby i třeba pomohly ostatním lidem. Věřím v IT komunitu, která by si měla pomáhat a do jisté míry spolupracovat.

Díky za pozornost :-)