Přejděte na >> nový blog <<
Z důvodů těžké spravovatelnosti tento blog zavírám a bude sloužit již jen jako archiv článků.
Weblog   Foto galerie   Odkazy   Implementace katedrálního portálu   ZČU-FAV

programovani

Phpblog: strip_tags a mezery

2006-02-08 19:06 | 3139 x   Programování

Řešil jsem nedávno celkem zajímavý problém v jazyce PHP. Dostal jsem text obsahující (X)HTML tagy a potřeboval jsem tento obsah překonvertovat do podoby, ve které by se dobře vyhledávalo. Ideální úloha pro funkci strip_tags.

Problém však nastává v okamžiku zjištění, že tato funkce smaže všechny tagy bez náhrady - nenahradí je žádným znakem, prostě je jen vymaže.

Příklad

HTML text:

<ul>
   <li>prvni polozka</li>
   <li>druha polozka</li>
 </ul>

Výstup:

 prvni polozkadruha polozka

Pro potřeby vyhledávání to žádný zásadní problém není, pokud nepotřebujete hledat celá slova. Pokud je ovšem požadováno výstup zobrazit uživateli nastává problém.

Funkce nahradí tagy mezerami

Hledal jsem na fórech nějakou fuknci, která by dokázala tagy nahradit mezerami, aby výstupní kód zůstal zobrazitelný. Nakonec jsem našel funkci, která to dokáže.

function strip_tags_by_spaces($text) {   

  $text = preg_replace('/</',' <',$text);   
  $text = preg_replace('/>/','> ',$text);   
  $desc = html_entity_decode(strip_tags($text));   
  $desc = preg_replace('/[\n\r\t]/',' ',$desc);   
  $desc = preg_replace('/  /',' ',$desc);
  return $desc; 

} 

Javablog: optimalizované použití stejných řetězců v rámci aplikace

2005-12-31 11:05 | 876 x   Programování

Celkem dlouho jsme se v práci přeli nad zajímavým problémem. Pokud chci vrátit prázdný string - řetězec z nějaké metody, jaký přístup je lepší. Nakonec k tomu připadl i dovětek: v rámci celé aplikace.

Já preferoval přístup:

    return new String();

na rozdíl od kolegy, který vždy vrací:

    return "";

Na první pohled stejný to vypadá stejně. V prvním případě se vytvoří nový objekt String a ten se odešle jako návratová hodnota z metody. Druhý případ funguje obdobně, jelikož metoda vrací instanci třídy String, ta musí vzniknout z prázného řetězce "". To znamená tak jako tak vytvořit jednu novou instanci třídy String.

Nejlepší způsob vracení prázdného String

Nakonec jsme zjistili, že je lepší preferovat druhý jmenovaný přístup, tedy return "";. Proč? Na stránce Java Language Specification ja část věnovaná tomuto problému: tady.

Výsek kódu příkladu

1  public static void main(String[] args) {     
2    String hello = "Hello", lo = "lo";
3    System.out.print((hello == "Hello") + " "); 
4    System.out.print((Other.hello == hello) +  " "); 
5    System.out.print((other.Other.hello == hello) + " "); 
6    System.out.print((hello == ("Hel"+"lo")) + " "); 
7    System.out.print((hello == ("Hel"+lo)) +  " "); 
8    System.out.println(hello == ("Hel"+ lo).intern()); 
9  }

Přičemž existuje již třída:

1  package other;
2  public class Other { static String hello = "Hello"; } 

Výsledek - co bude na obrazovce?

true true true true false true

Jak je to možné?

Jelikož práce VM s řetězci je velice optimalizovaná, průběžně si je ukládá a následně používá ty, které byli již jednou vytvořeny. Ostatně z tohoto příkladuje to jasně vidět. Funguje to evidentně i mezi třídami, balíky atd. Pokud použijete tento přístup, bude se v celé aplikaci vracet stejná instance bez vytváření dalších jiných.

Syntaxe byla zvýrazněna pomocí Code2HTML.

Code2HTML: zdrojové kódy (texty) Javy, C++, ... do HTML

2005-12-23 23:14 | Reakce [2] | 1940 x   Programování

Potřeboval jsem převést zdrojový kód Javy do HTML pro jeden z příkladů tak, aby byl hezky naformátován, pěkně barevný a odsazený, prostě tak jak to mají mazlíčci rádi Smile Jelikož jako editor pro psaní zdrojového kódu používáme nejlepší volně dostupný nástroj Eclipse, šel jsem nejdříve po něm, resp. po nějakém pluginu.

Našel jsem jedno rozšíření, které by to mělo umož?ovat. Jmenuje se Java 2 HTML, ze stejnojmenné německé domény: http://www.java2html.de. Problém je v tom, že mi nefunguje. Jednak pokud se cokoliv v menu nastaví, neuloží se to. Tzn. že pokud se povede vyprodukovat nějaký HTML kód nemá ani čísla řádek. Takže tohle řešení jsem přeskočil Undecided.

Code to HTML (Code2HTML) 

Naštěstí existuje služba jménem Code to HTML (Code2HTML), která dokáže přesně to, co jsem potřeboval. Převádí zdrojové kódy do "jazyka" HTML. Existují dvě řešení: první je online verze, která běží na serveru autora Petera Palfradera, druhak je zde možno stáhnout zdrojové kódy v perlu, které čítají kolem čtyř tisíc řádků.

Co Code2HTML umí?

Zvládá celkem dobře převod zdrojového kódu do jazyka HTML Tongue out. Zvládá spoustu zdrojových jazyků, umí je načíst z webové adresy souboru, z prostého vloženého textu nebo uploadovaného souboru jazyka java Smile. Zvládá také čísla řádek, buď prolinkovaná nebo pouze s kotvami. Jako poslední featura je možné přidat title výsledné HTML stránky.

Podporované jazyky zdrojového textu

  • Plain
  • Ada 95
  • C
  • C++
  • Java
  • Javascript
  • MakeFile
  • Pascal
  • Perl
  • SQL
  • Awk
  • M4
  • Groff

Příklad převodu Javy do HTML

1   /**
2   * Some comment.
3   */

4   class NetworkClassLoader extends ClassLoader {
5     String host;
6     int port;
7
8     public Class findClass(String name) {
9        byte[] b = loadClassData(name);
10       return defineClass(name, b, 0, b.length);
11     }
12
13      private byte[] loadClassData(String name) {
14        // load the class data from the connection
15        . . .
16      }
17    }

Java: získání SQL dotazu při použití třídy PrepareStatement

2005-11-13 11:37 | 1006 x   Programování

V našich projektech často využíváme databázi a stejně často člověk zabředne do složitých SQL dotazů, které obsahují několik zanořených částí.

Při vytváření SQL dotazu je lepší nechat dopl?ování proměnných na třídě PrepareStatement. Automaticky se doplní všechny apostrofy a další potřebné znaky, kterými se tyto proměnné musí obalit. Bohužel při lazení pak programátor ztrácí přehled jak přesně dotaz vypadá. Místo hodnot proměnných jsou otazníky.

Dlouho jsem hledal nějakou funkci, která by byla schopná zobrazit při naplnění proměnných přesně SQL dotaz, který bude proveden. Nakonec jsem na oracle fóru nalezl odpověd, že žádná taková funkce z principu této třídy neexistuje.

Potom jsem si všimnul, že při debugu aplikace, zobrazuje Eclipse při kliknutí na instanci třídy PrepareStatement přímo celý SQL dotaz. Proto stačí použít metodu toString() a získat tak SQL kód. Bohužel tato metoda stejně nevrací přesně SQL kód, který bude proveden. Občas chybí některé uvozovky, ale místo ručního plnění dat v SQL editoru to bohatě dostačuje.

PreparedStatement pstmt = conn.prepareStatement("INSERT INTO table "
    "(col1, col2, col3) VALUES (?,?,?)");

pstmt.setString(1"test value");
pstmt.toString();
pstmt.setString(2"test value2");
pstmt.toString();
pstmt.setString(3"test value3");
pstmt.toString();

pstmt.executeUpdate();
pstmt.close();

Oracle: jak na LIMIT, testy rychlosti

2005-10-23 22:12 | Reakce [1] | 1739 x   Programování

Jelikož jsem v práci řešil velké množství problémů s databází Oracle, tak se rád podělím o jeden z nich.

Oracle, bůch ví proč, nemá LIMIT. Nelze tedy napsat vybírat určitý počet prvků jednoduše tak, jak to umí třeba MySQL nebo Postgresql:

SELECT * FROM table LIMIT 10, 10;

Rownum

Oracle má místo toho rozporuplný ROWNUM. Každý vybraný řádek má ještě navíc jeden sloupec, který jednoduše určuje číslo řádku v daném výběru.

SELECT * FROM table WHERE ROWNUM BETWEEN 10 AND 20

Bohužel tento dotaz nefunguje, tak jak by měl. Nevrátí totiž vůbec nic. Kde je chyba, jsem nenašel ani v dokumentaci, přitom jsou tohoto problému plná fóra. Přitom dotaz končící ROWNUM<=10 vrátí naprosto korektní výsledek.

Další problém se naskýta tradičně při řazení na konci dotazu. Pokud je zde uvedena formule pro řazení např. ORDER BY sloupec. dojde k logickému: nejprve vybereme deset prvků, které potom seřadíme. Cílem ovšem bylo nalezení druhých deseti seřazených prvků.

?ešením jsou dvě možnosti:

SELECT table.* FROM (SELECT table.*, rownum as rnum FROM table)  WHERE rnum BETWEEN 10 AND 20

nebo

(SELECT table.* FROM table WHERE rnum <= 20) minus (SELECT table.* FROM table WHERE rnum <= 10)

Testy rychlosti

Sice je na první pohled zřejmé, která metoda by měla být rychlejší, je velice těžko říct, jak je Oracle optimalizovaný a jak to celé pracuje. Proto jsem otestoval na velkém množství dat obě dvě metody.

Tabulka měla 25 milionů položek, vždy klíč a určitou hodnotu, která byla reálným číslem. Primárním cílem bylo spočítat určitou hodnotu z druhých 12.5 milionů prvků tabulky.

Hodnoty pro sečtení počtu prvků pomocí COUNT pomocí minus

10:13:10 SQL> SELECT count(*) FROM
10:13:10   2  ((SELECT * FROM table
10:13:10   3      WHERE ROWNUM <= 25000000)
10:13:10   4  minus
10:13:10   5  (SELECT * FROM table
10:13:10   6      WHERE ROWNUM <= 12500000));

  COUNT
—————
  12500000

10:19:25 SQL>

Hodnoty pro sečtení počtu prvků pomocí COUNT pomocí ROWNUM:

10:24:46 SQL> SELECT COUNT FROM   
10:24:46   2  (SELECT table.*,rownum as rnum FROM table
4) 10:24:46   3  WHERE rnum BETWEEN 12500001 AND 25000000;

  COUNT
—————
  12500000

10:25:18 SQL>

Hodnoty pro sumě prvků pomocí SUM pomocí minus:

10:25:36 SQL> SELECT sum(value) FROM
10:29:36   2  ((SELECT * FROM BNSSYS.TBMATRIX_EWS_DEM_2004
10:29:36   3      WHERE ROWNUM <= 25000000)
10:29:36   4  minus
10:29:36   5  (SELECT * FROM BNSSYS.TBMATRIX_EWS_DEM_2004
10:29:36   6      WHERE ROWNUM <= 12500000));

SUM
—————
4862807240

10:35:33 SQL>

Hodnoty pro sumě prvků pomocí SUM pomocí ROWNUM:

10:35:45 SQL> SELECT sum(value) FROM   
10:36:45   2  (SELECT BNSSYS.TBMATRIX_EWS_DEM_2004.*,rownum as rnum FROM BNSSYS.TBMATRIX_EWS_DEM_200
4)
10:36:45   3  WHERE rnum BETWEEN 12500000 AND 25000000;

SUM
—————
4862807240

10:37:18 SQL>

Výsledky

První test trval 265 vteřin minusu vs. 32 vteřinám pro samostatným ROWNUM. Druhý dopadl obdobně: 297 vs. 33 vteřinám.

Je vidět, že použití minusu je řádově skoro desetkrát pomalejší než použití vnořeného selectu a rownumu.

Vhodné použití minusu je tam, kdy není zřejmé, co daný dotaz obsahuje. Třeba pokud je generován dotaz automaticky, nelze do něj nijak zásadně zasahovat je vhodné použít minus. Pro krátké operace rozdíl znatelný není. 

Australský Bunderberg Rum konečne hotov!

2005-01-17 00:20 | 1235 x   Programování
Na adrese www.bundabergrum.com.au jsme po půl roce práce, v minimálně, pěti lidech dokončili online presentaci světoznámé australské firmy Bundaberg a jejího oblíbeného rumu. K dispozici jsou dvě verze: pro rychlé připojení flash a pro pomalejší xhtml. Více o firmě najdete na adrese goexclusive.com.

Optimalizace pro vyhledávače (po milionté), aneb jak to je i není

2005-01-15 09:57 | Reakce [2] | 1126 x   Programování

Radek "Hulvát" Hulán na svém blogu opět zabývá myšlenkou, propranou od prázdnin už tisíce krát, optimalizací pro vyhledávače. Na tohlé téma byly napsány již desetitisíce řádků a každý webmáster strávil spousty hodin optimalizací svých svěřených stránek.

Všechno začala lupa.cz svou letní školou a letos pokračuje interval.cz seriálem SEO – Search Engine Optimization. Jenže původní texty lupy byly takové čekání, co přijde příště. Nic nového, co by každý neznal, řečeno nebylo. Pochopitelně, ten kdo si pracně vybudoval pozici na google.com nebude sdělovat zdarma, prostřednictvím internetu, svoje tajmenství, ale tvrdě ho prodá, jako Robert "SEO" Němec.

Pak přišli, většinou internetového obecenstva kritizované, Běžešelmovací růčovičky, které jsou zdárným příkladem, kam SEO mánie dorazila, ale pozornému optimalizátorovi nabízí jedinečný příklad hodný prozkoumání, jak a proč je ten první opravdu ten první. Lepší materiál se těžko někde najde.

Radek Hulán napsal nedávno velice pěkný článek Definitivní příručka pro dobré SEO. Vyjmenoval krátce a jasně to, jak zvýšit návštěnost webu. Přesně takhle dobře jednoduchý článek tu chyběl. Základ je v tom mít dobrý web, logickou a jasnou strukturu, optimalizovaná URL a slušnou novinařinou psát zajímavé texty. Bohužel poslední položka je až čtvrtá. Moje zkušenosti a dění posledních dní hovoří jasně. Měla by být první.

Ten, kdo zbortil hranice je Ostravák, který v součastnosti baví internetovou veřejnost. Tenhle bloger se dostal od 24. prosince minulého roku, tedy za 22 dní, na 21 tisíc čtenářů týdně. To je sen každého webmastera. Nepovedlo se to ničím jiným než slušnou novinařinou a skvělým obsahem, který se sám šíří internetem. Hezké adresy, výměnné linky jsou pěkné, ale se špatným obsahem k ničemu. Pokud přilákáte čtenáře přes vyhledávač, ti na zmateném webu nic nenajdou a příště se podobnému odkazu vyhnou. Z Ostravákova logu z Toplistu je jasné, že za těch pár dní získal neuvěřitelnou popularitu a odkazuje se na něj pár velice známých webů. Příchody z vyhledávačů jsem nezaregistroval vůbec. Tudy vede hlavní cesta.

A závěr? Ten je přece jasný! SEO je sama o sobě pěkná věda. Všechna kritéria jsou důležitá, ale to první je jasné. Mít dobrý a čtiví obsah. Zbytek se dostaví sám.

Broken link checker - najděte si špatné odkazy

2004-12-28 23:23 | 1601 x   Programování

Chcete zjistit zda máte na svém webu nějaké nefunkční nebo neexistující odkazy? Stačí se podívat na adresu http://www.submitshop.com/tools/linkchecker.html a vyplnit formulář s adresou Vaší domény a skript vykoná svoje. Prohledá stránku a všechny odkazy otestuje. Po pár minutách Vám vypíše seznam linků s jejich stavem. Zda existují, či ne. Link checker také dokáže zjistit jestli existují obrázky na stránce, soubory s kaskádovým stylem a nebo s JavaScriptem. Neocenitelná věc pro výstupní kontrolu webu především pro administrátory a programátory.

Vyhledávače a UTF-8

2004-12-26 22:57 | 1541 x   Programování

Publikační systém Xaraya, do kterého jsem převedl celý web, podporuje standardně kódování znaků v UTF-8. Jedná se o bytově variabilní formát. Více se můžete dočíst třeba na intervalu. Myslel jsem si, že si s ním vyhledávače poradí bez problémů. Tedy až do té doby než jsem pustil Poodle Predirector. Ten by měl na požádání ukázat stránku, tak jak ji vidí google.com. Podle všeho by si měl s tímto kódováním poradit. To samé Jyxo. Bohužel Poodle ukázál změť znaků, která rozhodně nevypovídá o jeho schopnosti číst korektně UTF-8. Jal jsem se tedy problém vyřešit, bohužel nepřišel jsem na jedinou věc, která by byla v hlavičče špatně. Kódování je zadáno korektně: <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />. Problém by mohl být buď neudaný jazyk, který by na to vliv mít neměl, nebo spíše, to že si s UTF-8 Poodle neporadí. Alespo? s českými znaky. Uvidíme při prvním indexování.

Dodatek: Po hledání podobných problémů jsem zjistil, že chyba je asi na straně Poodle Predirector. V diskuzi na jakpsatweb.cz si autorka webu tucnak.cz stěžuje, že jí google stránky špatně indexuje. Po zadání slova punčocháče měla problém s češtinou. Nakonec byla chyba ve špatně zadané hlavičce, která je již v současné verzi v pořádku. Nechal jsem tyto stránky projít predirectorem a výsledek je stále špatně. V google.com, ale vše již běží bez problémů. Jsem zvědav, jak stránky dopadnou při první indexaci. Zatím k ní, ani na google ani na jyxo nedošlo.