PDA

Pogčedajte punu verziju : PHP + hardkodirani šifrarnik


srdjan
16. 03. 2007., 00:33
Hi!

Imam pitanje jedno, vezano za upotrebu šifrarnika (PHP/MySQL).

Sve stringove i druge podesive variable držim u 3 tabele:

- VAR
- VALUE (child od VAR)
- VALUE_LOCAL (child od VALUE_LOCAL)

Tako da, na primer, za tekst koji se ispisuje na tasteru "Login" idu sledeći podaci:

Tabela VAR: "UI"
Tabela VALUE: "BUTTON_LOGIN"
Tabela VALUE_LOCAL: "Login" (za engleski)
Tabela VALUE_LOCAL: "Prijava" (za srpski)

E sad, ovo je sve uglavnom hard-codirano i sa malo podataka ne radi loše. Funkcija GetString("UI", "BUTTON_LOGIN", $language) vrati ono što treba.

Zanima me postoji li način da se ovo sve učita jednom (nešto tipa SELECT * FROM VAR, VALUE, VALUE_LOCAL WHERE veza po ID-ju) i onda "iz memorije" serviraju stringovi web stranama.

Izgleda mi loše da za svaki poziv PHP skripta radim ovaj SELECT, a još lošije da radim SELECT za svaki string koji mi treba.

Nisam baš rodjen kao PHP programer :) tako da mi treba savet, nadam se da ste skapirali šta sam hteo da pitam.

Pozdrav,
S.

ivanhoe
16. 03. 2007., 02:29
ne razumem poentu VAR tabele? Jel ona treba da omoguci neke sekcije unutar prevoda?

ja obicno sve lokalizacije drzim u fajlovima, jer je tako mnogo lakse za masovno prevodjenje, samo iskopiras fajl i prevedes sve sto treba..

ppavlovic
16. 03. 2007., 02:40
Ja imam takvo stupidno resenje za moj sajt... koji je btw za 99.9% na srpskom. :(

Elem, da bi ubrzao izvlacenje stringova iz baze, uradi sledece:
1) zaboravi na normalizaciju tabela i sve to stavi u jednu tabelu
Moja tabela ima sledeca polja:

lang_code char(2), // SR, EN, FR
name varchar(255), // labela koja se prevodi
description varchar(255), // opis labele
value text, // vrednost labele u zavisnosti od jezika
topic varchar(30) // sekcija na koju se odnosi prevod: General, UI, Messages, Errors, Mail

2) uradi "Select * From translation_tabela" i prebaci rezultat u jedan array tipa


$translation['en']['LOGIN'] = 'Login';
$translation['sr']['LOGIN'] = 'Prijava';
...etc...


ili ti

$translation = array('en' => array( 'LOGIN' => 'Login', 'LOGOUT' => 'Logout'),
'sr' => array('LOGIN' => 'Prijava', 'LOGOUT' => 'Odjava');

3) prepravi tvoju funkciju GetString() da cita vrednost iz $translation niza, a ako nije isset() taj clan niza, onda uradi SELECT za vrednoscu iz baze za default jezik

4) ako imas eAccelerator, APC cache ili mmcache, stavi promenljivu $translation u shared memory.
4a) ako nemas doticne module, onda serijalizuj promenljivu $translation i stavi je u bazu ili filesystem (sta god ce od ta dva bude brze) pa onda unserialise... Ili jos bolje, napravi skripticu koja ce da napravi jedan PHP fajl koji ce imati sadrzinu

$translation = array('en' => array( 'LOGIN' => 'Login', 'LOGOUT' => 'Logout'),
'sr' => array('LOGIN' => 'Prijava', 'LOGOUT' => 'Odjava');

i koji ces da inkludujes na pocetku svake skripte. Svaki put kad izmenis/dodas neki translation string u bazi, pozovi neku utility skriptu koja ce da regenerise fajl sa $translation. Ovo jos bolje radi ako imas instaliran Zend Accelerator

Ima li neko bolju/optimizovaniju ideju?

srdjan
16. 03. 2007., 08:46
@ivanhoe

Cela struktura nije namenjena samo lokalizaciji, već je šifrarnik za "sve i svašta", npr. za VAR="admin_setup", recordi u tabeli VALUE imaju vrednosti razunih parametara sajta, mogu biti i numeričke i sl. A samo za stringove se "gleda" u VALUE_LOCAL

@ppavlovic

Hvala za ideje, naročito pod 4...

Obzirom da će tekst biti menjan relativno retko, ideja sa generisanjem PHP koda na osnovu podataka iz tabela nije uopšte loša.

ivanhoe
16. 03. 2007., 11:43
Ima li neko bolju/optimizovaniju ideju?

mozda da se ne drze svi jezici u istoj tabeli.. u jednom trenutku tebi treba samo jedan jezik, tako da ima smisla to sve podeliti na zasebne tabele..

takodje, mozda bi imalo smisla podeliti spisak reci po stranicama gde se koriste, pa ucitavati u memoriju samo ono sto ti je potrebno za trenutnu stranu..

zextra
16. 03. 2007., 14:37
@srdjan: ja sam takvo resenje koristio jednom davno... Budz varijanta je da recimo u funkciju koju stalno pozivas (GetString) stavis parce koda koje proverava da li je globalna varijabla npr. $translations definisana, i ako nije, da je inicijalno popuni bitnim podacima (prevodima i stringovima u tvom slucaju, jel), a zatim, svako naredno pozivanje funkcije samo koristi vec ucitane podatke...

Naravno, postoje i elegantnija resenja, ali ovo je najblize implementaciji u tvom slucaju.