LINUXZONE






 >> Hlavní stránka

(1740/07.09.2010)


 >> Administrace

(161/05.08.2010)


 >> Literatura

(311/07.09.2010)


 >> Bezpečnost

(345/03.09.2010)


 >> Programování

(307/19.04.2010)


 >> Distribuce

(97/09.06.2010)


 >> Síťování

(86/03.06.2010)


 >> Lokalizace

(10/15.09.2004)


 >> Aplikace

(176/12.08.2010)


 >> Multimedia

(32/31.03.2006)


 >> Hardware

(45/02.03.2007)


 >> Začínáme

(228/24.06.2010)


 >> Aktuálně

(562/06.09.2010)


 >> RELAX

(209/02.09.2010)


 >> Jinde vyšlo

přehled ostatních serverů




 Přihlášení




Login:
Heslo:
 uložit v prohlížeči


Nejste-li ješte zaregistrováni, můžete tak učinit zde.





 Vyhledávání




Hledaný výraz:
v klíčových slovech
v titulku
v anotaci
v textu








 Reklama









 Servis




*   Vaše náměty a připomínky
Máte k Linuxzone.cz nějaké připomínky nebo náměty? Našli jste na stránkách chybu? Dejte nám o tom vědět pomocí formuláře nebo v diskuzi.
Komentářů: 30
*   Podpořte Linuxzone.cz
Chcete podpořit náš server umístěním odkazu nebo zveřejněním backendu? Zde najdete vše potřebné.
*   Pište pro Linuxzone.cz
Máte zájem podílet se na obsahu Linuxzone.cz ať už jako redaktoři nebo i jinak? Dejte nám o sobě vědět!





 Aktuálně z bezpečnosti




-- 
6.12.2005, 19:01
Na serveru informit.com vyšla ukázková kapitola týkající se práce s řetězci z knihy Secure Coding in C and C++. (lz)

-- 
3.12.2005, 12:34
Bugtraq: Format String Vulnerabilities in Perl Programs. (lz)

-- 
3.12.2005, 12:32
Linux Advisory Watch December 2nd 2005. (lz)

-- 
23.10.2005, 13:28
Rozhovor na téma klasické zálohování versus CDP. (lz)

-- 
23.10.2005, 13:24
Linux Advisory Watch October 21st 2005. (lz)

další >>





 Aktuálně o software




-- 
6.12.2005, 19:07
Potřebujete-li pod linuxem rozchodit bezdrát založený na čipsetech Broadcom 43xx, konečně existuje linuxový ovladač. (lz)

-- 
6.12.2005, 19:04
Byla uvolněna verze Xen 3.0.0 virtualizační technologie XEN. (lz)

-- 
6.12.2005, 18:59
Byla uvolněna verze X11R6.9/X11R7 RC 3 grafickérho rozhraní X Window System. (lz)

-- 
3.12.2005, 12:45
Co je nového okolo projektu Amanda (open source zálohovací software)? Více na osnews.com. (lz)

-- 
3.12.2005, 12:40
Jak to akuálně v linuxu vypadá s podporou SATA.. (lz)

další >>





 Aktuálně z IT




-- 
3.12.2005, 12:51
Novellu se daří prodej linuxových produktů, oproti loňskému roku se Novell dočkal výrazného nárůstu. (lz)

-- 
3.12.2005, 12:48
Třetí verzi licence GPL by měla být publikována během jara 2007. (lz)

-- 
23.10.2005, 13:20
V Peru nyní mají zákon, který umožňuje nasazení open source software ve vládní správě. (lz)

-- 
23.10.2005, 13:14
Proč se Microsoft bojí Google? (lz)

-- 
27.9.2005, 22:01
Peru má zákon podporující free software. (lz)

další >>





 Nejčtenější články




-- 
Virtualizace - Praktický průvodce

-- 
Novinky ze světa svobodného software (21/2010)

-- 
Novinky ze světa svobodného software (22/2010)

-- 
Security Digest (21/2010)

-- 
Bezpečnost bezdrátové komunikace

-- 
Prodej svobodného software? (2/2)

-- 
Patentová reforma nestačí

-- 
Prodej svobodného software? (1/2)

-- 
Gamesárium [140]

-- 
Novinky ze světa svobodného software (23/2010)






 Nejlepší články




-- 
Security Digest (22/2010)

-- 
Virtualizace - Praktický průvodce

-- 
Security Digest (21/2010)

-- 
Novinky ze světa svobodného software (21/2010)

-- 
Novinky ze světa svobodného software (23/2010)

-- 
Novinky ze světa svobodného software (22/2010)

-- 
Prodej svobodného software? (2/2)

-- 
Bezpečnost bezdrátové komunikace

-- 
TCP/IP v kostce

-- 
Patentová reforma nestačí






 Anketa




Používáte nějaké rozšíření bezpečnostního modelu linuxového jádra?

Openwall (18%)

LIDS (12%)

Pax/Grsecurity (3%)

SELinux (6%)

RSBAC (1%)

jiné (1%)

používám standardní jádro (59%)







Linuxzone.cz - server o Linuxu pro programátory, administrátory a fanoušky.
Provozuje společnost Impossible.
ISSN: 1213-8738





PHP a čeština IV. - vícejazyčné aplikace, 2. část

Hlavní výhodou databáze je, že přistupujeme pouze k datům, které potřebujeme. Databázový stroj (server) může samozřejmě pracovat s daty různým způsobem, avšak určitě efektivněji, než jak se s nimi pracuje přímo v PHP. Pro demonstraci principů práce jsem zvolil databázový systém MySQL, který se v kombinaci s PHP používá velmi často, je velmi výkonný a dobře dostupný díky svým licenčním podmínkám. Rozdíly oproti jiným relačním databázím (PostgreSQL, Firebird, Oracle atd.) jsou však minimální a tak lze program na tyto systémy snadno upravit.

Vícejazyčné aplikace s použitím databáze

Prvním krokem bude opět návrh způsobu uložení dat, tedy datový model. V tomto případě to bude velmi jednoduché, protože si vystačíme s jedinou tabulkou. Klíčovým atributem bude onen identifikační klíč známý z předchozího příkladu. Ostatní atributy budou jednotlivé jazykové mutace. Zatím jich je pevný počet, ale je možné i přidávání dalších jazyků za provozu.

Předpokládejme, že délka klíče nepřekročí 50 znaků, proto použijeme datový typ s touto délkou. Naopak délka ostatních textů může být libovolná - ohraničíme ji hodnotou 65535 bajtů (používáme UTF-8, proto se znaků může vejít méně!). Tabulku vytvoříme takto (vytvoří se také index nad klíčem):

CREATE TABLE Texty (klic VARCHAR(50) NOT NULL PRIMARY KEY, lang_cs TEXT,
  lang_en TEXT, lang_de TEXT, UNIQUE INDEX ind (klic))

A můžeme tabulku naplnit daty. To se dá různě automatizovat, teď si ale vystačíme s "ručním" naplněním. Data budou téměř identická jako u první metody. Pozor na kódování, musí být UTF-8!

INSERT INTO Texty VALUES('nadpis','Testovací stránka','The testing page','Die Testseite');
INSERT INTO Texty VALUES('popis',
  'Toto je vícejazyčná testovací stránka.',
  'This is a multilingual testing page.',
  'Das ist eine mehrsprachige Testseite.');
INSERT INTO Texty VALUES('demonstrace',
  'Demonstruje mechanismus s použitím databáze.',
  'Is demonstrates the mechanism with database.',
  'Es demonstriert der Mechanismus mit Datenbasis.');

Databáze je tedy naplněna, můžeme se pustit do implementace PHP části. Bude to opět velmi snadné. Přístup k databázi zahrneme do funkce:

<?
function text_by_lang($db,$klic,$lang) {
  $sql = "SELECT $lang FROM Texty WHERE klic='$klic'";
  $res = mysql_query($sql,$db);
  $ta = mysql_fetch_row($res);
  return $ta[0];
}
?>

Celé to pak bude vypadat velmi podobně jako v předchozím případě:

<?
require("funkce.php");              // Přidáme soubor s funkcí
header("Content-Type: text/html; charset=utf-8");     // Typ dat a znaková sada
$jazyk = $_GET["lang"];             // Nastavení jazyka podle požadavku
if ($jazyk == "") $jazyk = "cs";    // Není-li určen jazyk, použije se čeština
$con = mysql_connect("127.0.0.1","uzivatel","heslo"); // Připojení databáze
$jazyk = "lang_$jazyk";             // Úprava názvu jazyka
?>

<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<?
echo "<title>";
echo text_by_lang($con,"nadpis",$jazyk);
echo "</title>\n";
?>

</head>

<body>

<?
$str = text_by_lang($con,"nadpis",$jazyk);
echo "<h1>$str</h1>\n";

$str = text_by_lang($con,"popis",$jazyk);
echo "<p>$str</p>\n";

$str = text_by_lang($con,"demonstrace",$jazyk);
echo "<h1>$str</h1>\n";


</body>
</html>

V uvedeném příkladu nejsou ošetřeny chyby, které mohou nastat. Také uvedená implementace připojení na databázi není úplně nejbezpečnější, ale v zájmu jednoduchosti jsem tyto prvky vypustil. Pro velké množství projektů si s podobně jednoduchou implementací vícejazyčné podpory vystačíme. Teprve u těch opravdu velkých, a také u těch, kde nám opravdu záleží na stabilitě, použijeme něco, co bylo za tímto účelem vytvořeno a co nabízí velké možnosti: balík Translation z knihovny PEAR.

Využití balíku Translation

Než se budeme zabývat samotným balíkem Translation, bude dobré nastínit, co je vlastně knihovna PEAR. PEAR je zkratka pro "PHP Extension and Application Repository". Na začátku byla myšlenka, že by se mělo shromáždit všechno, co bylo v PHP vytvořeno, co chce někdo nabídnout ostatním a co je obecněji použitelné. A nejen shromáždit, ale také uspořádat, nastolit určitou "štábní kulturu", vytvořit vhodný model pro údržbu kódu a jeho distribuci a v neposlední řadě poskytnou pro toto všecho potřebnou podporu (WWW stránky, zrcadla, konference atd.).

Kód v PEAR je uložen v balících, každý balík obsahuje kód k určitému účelu (analogie s balíky u Javy). Balíky jsou uspořádány do stromové struktury podle svého účelu. Na psaní kódu se vztahují pravidla nazývaná PCS (PEAR Coding Standards).

Všechny balíky jsou uloženy v centrální databázi, ke které je přístup přes HTML stránky a také prostřednictvím XML-RPC (pro automatizovaný přístup). Balíky se jsou k dispozici pro stažení protokolem HTTP, jsou komprimovány pomocí GZIP a obsahují popis v XML souboru. Pro údržbu verzí se používá systém CVS.

Zvláštní částí PEAR jsou PHP Foundation Classes (PFC). Tato složka obsahuje balíky zaměřené na kvalitu, kompatibilitu a stabilitu. Platí zde nejpřísnější kritéria. Do základní instalace PHP jsou z celého PEAR přibírány komponenty pouze právě z PFC. Bylo by dobré zmínit ještě ozančení PECL (PEAR Extension Code Library). Jsou to rozšíření PHP; vztahují se na ně standardy PHP, ale jsou šířeny jako balíky PEAR.

Jedním z balíků je také již zmíněný Translation. Vytvořili ho polští programátoři s cílem získat snadno použitelný a robustní nástroj pro snadnou tvorbu vícejazyčných PHP aplikací. Prostřednictvím PEAR ho dávají k dispozici pro všeobecné použití.

Ke vlastnostem a schopnostem balíku Translation patří:

  • dynamické přidávání a odebírání jazyků
  • dynamické přidávání a odebírání textů pro jazyky
  • parametrizovatelné dotazy (pro výběr jazykové mutace textu)
  • získání META tagu do HTML hlavičky
  • ošetření chyb
  • efektivní práce s databází

Pro funkci balíku je samozřejmě nezbytná instalace základního balíku PEAR; v posledních verzích PHP (konkrétně od 4.3.0) je již PEAR přímo součástí distribučního balíku PHP.

Balík Translation obsahuje dva PHP soubory. V jednom z nich se nachází samotná třída Translation, ve druhém jsou pomocné funkce určené pro manipulaci s databází. Pro přístup k databázi se využívají prostředky poskytované PEAR. Databáze vypadá tak, že v jedné tabulce obsahuje jednotlivé jazyky včetně souvisejících dat a pak je pro každý jazyk zvláštní tabulka. Pro tři jazyky (viz předchozí příklady) by databáze vypadala takto:

CREATE TABLE tr_langsavail (lang_id CHAR(2) NOT NULL default '' PRIMARY KEY,
  name VARCHAR(128) DEFAULT NULL, metatags LONGTEXT, errortext LONGTEXT,);
CREATE TABLE tr_strings_cs (page_id VARCHAR(16) DEFAULT NULL,
  string_id VARCHAR(32) NOT NULL DEFAULT '', string LONGTEXT,
  UNIQUE INDEX page_id (page_id,string_id));
CREATE TABLE tr_strings_en (page_id VARCHAR(16) DEFAULT NULL,
  string_id VARCHAR(32) NOT NULL DEFAULT '', string LONGTEXT,
  UNIQUE INDEX page_id (page_id,string_id));
CREATE TABLE tr_strings_de (page_id VARCHAR(16) DEFAULT NULL,
  string_id VARCHAR(32) NOT NULL DEFAULT '', string LONGTEXT,
  UNIQUE INDEX page_id (page_id,string_id));

Již z popisu tabulek je vidět, že můžeme textové řetězce rozlišovat také podle stránek, což se hodí tehdy, když potřebujeme rozlišovat řetězce umístěné na různých stránkách. Do vytvořené databáze vložíme data, zatím jen ta, která popisují jednotlivé jazyky:

INSERT INTO tr_langsavail VALUES ('cs', 'Česky',
  '<meta http-equiv="content-type" Content="text/html; charset=utf-8">', 
  'Česká verze nebyla nalezena.');
INSERT INTO tr_langsavail VALUES ('en', 'English', 
  '<meta http-equiv="content-type" Content="text/html; charset=utf-8">', 
  'English version not found.');
INSERT INTO tr_langsavail VALUES ('de', 'Deutsch', 
  '<meta http-equiv="content-type" Content="text/html; charset=utf-8">', 
  'Die deutsche Version nicht gefunden.');

Potom můžeme vložit i texty v jazykových mutacích. Rozlišení podle stránek zde zůstane nevyužito:

INSERT INTO tr_strings_cs VALUES ('', 'nadpis', 'Testovací stránka');
INSERT INTO tr_strings_en VALUES ('', 'nadpis', 'The testing page');
INSERT INTO tr_strings_de VALUES ('', 'nadpis', 'Die Testseite');
INSERT INTO tr_strings_cs VALUES ('', 'popis',
  'Toto je vícejazyčná testovací stránka.');
INSERT INTO tr_strings_en VALUES ('', 'popis',
  'This is a multilingual testing page.');
INSERT INTO tr_strings_de VALUES ('', 'popis',
  'Das ist eine mehrsprachige Testseite.');
INSERT INTO tr_strings_cs VALUES ('', 'demonstrace',
  'Demonstruje mechanismus s použitím PEAR balíku Translation.');
INSERT INTO tr_strings_en VALUES ('', 'demonstrace',
  'Is demonstrates the mechanism using PEAR Translation package.');
INSERT INTO tr_strings_de VALUES ('', 'demonstrace',
  'Es demonstriert der Mechanismus mit PEAR Translation Paket.');

Protože práce s texty v různých jazycích je řešena v rámci balíku Translation, můžeme přejít ihned k implementaci vlastní stránky generované pomocí PHP:

<?
require_once("translation/translation.class.php");
$tr = new Translation ("Test", $_GET['lang'], "mysql://uzivatel:heslo@127.0.0.1/translation");
?>

<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
<html>
<head>

<?
echo "<title>"
  $tr->gstr("nadpis")
  "</title>";
echo $tr->getMetaTags();
?>

</head>

<body>


echo "<h1>"
  $tr->gstr("nadpis") 
  "</h1>";
echo "<p>"
  $tr->gstr("popis")
  "</p>";
echo "<p>"
  $tr->gstr("demonstrace")
  "</p>";


</body>
</html>

Tento PHP kód je ještě jednodušší než ty předchozí. A to není zapotřebí ani plnit ručně databázi, protože i toto dokáže zajistit balík Translation. Je pouze nutné, aby databáze existovala. Jazyk se přidá voláním k tomu určené funkce. Potom je samozřejmě ještě třeba přidat všechny texty v daném jazyce. Přidání jazyka si můžeme ukázat např. na slovenštině (omlouvám se za případné jazykové nedostatky):

<?
createNewLang("sk","Slovensky", "",
  "<meta http-equiv="content-type" Content="text/html; charset=utf-8">",
  "mysql://uzivatel:heslo@127.0.0.1/translation");
addTranslation("","nadpis","Testovacia stránka",
  "mysql://uzivatel:heslo@127.0.0.1/translation");
addTranslation("","popis","Toto je viacjazyčná testovacia stránka",
  "mysql://uzivatel:heslo@127.0.0.1/translation");
addTranslation("","demonstrace","Demonštruje mechanizmus za použitia PEAR balíka Translation",
  "mysql://uzivatel:heslo@127.0.0.1/translation");
?>

Tento způsob přidávání jazyků má jednu nevýhodu. Neumožňuje definovat chybový text pro případ, že daný text nebyl nalezen. Doufejme, že v novějších verzích balíku bude již toto vyřešeno.

Jazyky je možné podobným způsobem také odebírat. K tomu slouží funkce removeLang(). Odebrat lze i textové řetězce, a to vždy pro všechny jazyky - pomocí funkce removeTranslation().

Ve třídě Translation jsou ještě dvě zajímavé metody, které stojí za to uvést. První má název getLangName() a vrací název aktuálního jazyka. Metoda getOtherLangs() je k ní komplementární, vrací pole obsahující všechny ostatní jazyky a hodí se k přepínání mezi jednotlivými mutacemi.

Metoda gstr(), která realizuje načtení správného řetězce z databáze, má, jak již bylo řečeno, možnost parametrizace. Běžně stačí pouze uvést klíč pro výběr řetězce, ale možnosti jsou podstatně větší. Jednou z těchto možností je explicitní specifikace stránky pro výběr textu. K tomu se používá tzv. tečková notace, tedy tvar stránka.klíč (jinak se použije stránka určená při vytváření instance třídy Translation).

Vlastní parametrizace se však provádí až druhým argumentem. Ten má podobu asociativního pole, jehož prvky obsahují příslušné parametry. Tyto prvky mohou být až tři:

  • action - výběr akce k provedení (viz hodnoty dále)
    • normal - implicitní hodnota; vybere se text podle aktuálního jazyka
    • translate - text se vybere podle jazyka specifikovaného v parametru lang_id
  • lang_id - určuje explicitně jazyk pro výběr textu. V případě nastavení action na translate je uvedení povinné. Naopak by se parametr neměl užívat v případě action na hodnotě normal, protože se nevyužívá informací uložených v cache.
  • optimization - způsob optimalizace dotazů, rozdělení zátěže mezi PHP serverem a databázovým serverem. Používá se pouze při action nastavené na translate. Může nabývat těchto hodnot:
    • php - větší počet jednoduchých dotazů. Vhodné v případě, kdy PHP a databáze běží na stejném stroji.
    • db - jediný složitější dotaz. Vhodné pro případy, kdy běží databáze na jiném stroji než PHP. Nefunguje pro databázové systémy, které nepodporují vnořené dotazy.

Závěr

Ačkoliv jsem se nezmínil o všech aspektech "soužití" češtiny a PHP, i tak je zcela zřejmé, že se jedná o velmi komplexní problematiku. Všechny oblasti je třeba řešit současně, čímž se samozřejmě situace dále komplikuje. Jak se ale přitom ukazuje, nástrojů pro řešení těchto problémů je mnoho a máme opravdu z čeho vybírat. Proto věřme, že se tyto nástroje budou využívat na sto procent a my se budeme do budoucna setkávat pouze s takovými WWW stránkami, které budou z tohoto hlediska zcela bez problémů.

Odkazy


Tento článek vyšel v prvním čísle časopisu PHP Magazín, který vydává společnost Software Media, s.r.o.

Další části seriálu:

Autor: Lukáš Jelínek, 16. 10. 2003, 00:00
Sekce Lokalizace, Komentářů: 6
Průměrné hodnocení: 3,02

o Poslat e-mailem
o Tisk článku
o Uložit do profilu


 Přispějte nám




Líbil se Vám tento článek? Můžete ho ocenit zavoláním na tel. číslo 906 460 134.
Cena hovoru za 1 minutu je 46 Kč.





 Hodnocení článku




Článek hodnotím jako:  [1] výborný   [2] dobrý   [3] průměr   [4] špatný   [5] hrůza  





 Komentáře




--

Tom, 22. 04. 2008 19:08
Jiná znaková sada












--

Lukáš Jelínek, 23. 10. 2003 01:00
Re: bezpecnost












--

Michal Burda, 22. 10. 2003 13:21
bezpecnost












--

Lukáš Jelínek, 16. 10. 2003 19:50
Re: cachovani












--

PEpa, 16. 10. 2003 14:10
RE: CACHOVANI












--

lukas jirka, 16. 10. 2003 00:15
Cachovani















PŘIDAT KOMENTÁŘ ZOBRAZ VŠE >>










2002 © Impossible, s.r.o.   >> Kontaktujte redakci >> Právní upozornění >> Reklama