Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Wybór jezyka na stronie
Forum PHP.pl > Forum > Przedszkole
djtomaszq
Chciałbym zmieniać język na stronie z POL na ENG i odwrotnie.

1. Jak byście doradzali aby się do tego zabrać ?

2. Czy mój POMYSŁ jest OK?
POMYSŁ: jedyne co na razie przyszło mi do głowy to:
Zmiana jeżyka odbywa się po wciśnieciu jednego z dwóch przycisków POL lub ENG na stronie głównej o przenosi do pliku w którym wykonuje się skryp gdzie łączzy się z bazą danych i w zależności od wybranego języka pobiera wszystkie wiersze z bazy mysql i przypisuje w zmienne sesyjne, które są ustawiane na stronie gdzie powinien być tekst.

nospor
I teraz zmieniasz jakis tekst bo cos tam i user zobaczy zmiane dopiero na drugi dzien jak mu sesja wygasnie...

Tekst ma byc pobierany w momencie wyswietlania a nie w zadnej sesji. Mozesz oczywiscie trzymac go w jakims cache by za kazdym razem nie latac do bazy.
Zas samo info o jezyku ma byc zawarte w linku a nie jednorazowej akcji. np:
en.mojastrona.pl/
lub
mojastrona.pl/en
djtomaszq
ok, to popraw mnie jeśli źle rozumiem

  1. <a href="polski.php">Zmień na polski </a>

i tak samo z ang
a w plikach polski.php etc. trzymać skrypt który pobiera z bazy słówka i wyświetla w cache ?
nigdy nie bawiłem sie z cache to nie wiem jak to wygląda dodaamm.
emstawicki
Jeżeli mogę się wtrącić, to uważam, że adres powinien przekazywać tylko jaki to jest język, a skrypt uniwersalny.
nospor
@emstawicki w ogole nie powinno byc zadnego skryptu.

@djtomaszq napisalem przeciez ze nie ma byc twojego zadnego skryptu na zmiane jezyka.
Jezyk masz miec w adresie strony zas potem gdzies tam w kodzie funkcja, ktora zwraca ci tekst dla danego jezyka

  1. blabla <?php echo trans('jakisklucz') ?>blabla

I funkcja trans() na podstawie jezyka w linku zwroci ci tekst dla klucza "jakisklucz". I czy ona to pobierze z bazy czy z cache to juz jej sprawa, ciebie nie interesuje wink.gif
djtomaszq
Łapie o co chodzi ale powoli... oneeyedsmiley02.png

w bazie mysql tabeli translator kolumny:
klucz | PL | ENG
gracz | zawodnik | player


  1. function ($tekst)
  2. {
  3. <a href="index.php/?lang=PL">PL</a>
  4.  
  5. //laczenie z baza itp
  6. $zapytanie = $pol->query("SELECT '$_GET['lang']' FROM translator WHERE klucz = '$tekst'");
  7. //przypisuje
  8. ...
  9. <?php echo trans('gracz') ?>
  10. }


.. coś trafiłem czy dalej leżakuje w tym przedszkolu?
nospor
Napisz to porzadnie a nie jakis pseudo kod ktory teraz wyglada fatalnie i trudno stwierdzic czy zalapales czy nie wink.gif

Nie PL a pl

I tabela nie ma miec kolumn PL EN tylko ma miec kolumny
key | lang | text

przykladowe rekordy
key1 | pl | klucz1
key1 | en | key1
key2 | pl | klucz2
key2 | en | key2
djtomaszq
  1. <?php
  2. function trans($text)
  3. {
  4. require_once "connect.php";
  5.  
  6. try{
  7. $polaczenie = new mysqli($host, $db_user, $db_password, $db_name);
  8. if($polaczenie->connect_errno !=0)
  9. {
  10. throw new Exception($polaczenie->mysqli_connect_errno());
  11. }else
  12. {
  13. $lang = $_GET['strona'];
  14. if(!$zapytanie = $polaczenie->query("SELECT text FROM translate WHERE lang = '$lang' AND key = '$text'"))
  15. {
  16. throw new Exception($polaczenie->error);
  17. }else
  18. {
  19. $wiersz = $zapytanie->fetch_assoc;
  20. }
  21.  
  22. $polaczenie->close();
  23. }
  24. }catch(Exception $e)
  25. {
  26. echo $e;
  27. }
  28.  
  29. return($wiersz['text']);
  30. }
  31.  
  32. echo trans('key1');
  33. ?>
  34.  
  35.  
trueblue
I za każdym razem wykonujesz zapytanie do bazy, a co gorsze za każdym razem otwierasz połączenie z bazą.
Wyobraź sobie, że na stronie masz do przetłumaczenia chociażby 100 etykietek.

Lepiej pobierz raz wszystkie tłumaczenia do tabeli i odczytuj w razie potrzeby już właśnie z niej.
emstawicki
@nospor
Chodziło mi bardziej o to żeby skrypty/modele, które wczytują dane były uniwersalne - tym bardziej jeżeli chodzi potem o wielojęzykowość innych treści.
@trueblue ma rację. Pobierz wszystkie zmienne językowe
nospor
@ djtomaszq tak, teraz lepiej i teraz juz tylko to optymalizowac smile.gif
Jak juz wspomniano dane masz pobrac raz a potem ciagnac je z tabeli juz pobranej by nie latac do bazy po kazdy klucz.
Skoro korzystasz z funkcji, to mozesz zapisac to w zmiennej statycznej w funkcji za pierwszym razem, a potem odwolywac sie juz do tej zmiennej
Mozesz tez zapisac to w cache by przy kazdym request do strony nie wczytywac tego i tak ponownie z bazy.
Jesli tekstow bedziesz mial duzo mozesz pokusic sie podzielic to na moduly jeszcze i wowczas zamias
key
bedziesz mial
module.key
I zamiast pobierac wszystkie teksty bedziesz pobieral tylko dla danego modulu

@emstawicki wybacz, zrozumialem ze mowisz o tych dwoch konkretnych skryptach polski.php oraz english.php smile.gif
djtomaszq
ok czyli tak by to wyglądało lepiej ?

  1. <?php
  2. require_once "connect.php";
  3.  
  4. try{
  5. $polaczenie = new mysqli($host, $db_user, $db_password, $db_name);
  6. if($polaczenie->connect_errno !=0)
  7. {
  8. throw new Exception($polaczenie->mysqli_connect_errno());
  9. }else
  10. {
  11. $lang = $_GET['strona'];
  12. if(!$zapytanie = $polaczenie->query("SELECT text, klucz FROM translate WHERE lang = '$lang'"))
  13. {
  14. throw new Exception($polaczenie->error);
  15. }else
  16. {
  17. $ile = $zapytanie->num_rows;
  18.  
  19. for($i=0; $i < $ile; $i++)
  20. {
  21. $wiersz[$i] = $zapytanie->fetch_assoc();
  22. }
  23. }
  24.  
  25. $polaczenie->close();
  26. }
  27. }catch(Exception $e)
  28. {
  29. echo $e;
  30. }
  31.  
  32. function trans($text)
  33. {
  34. global $ile;
  35. global $wiersz;
  36.  
  37. for($i=0; $i < $ile; $i++)
  38. {
  39. if($wiersz[$i]['klucz'] == $text) return $wiersz[$i]['text'];
  40. }
  41. }
  42.  
  43. echo trans('key1');
  44. ?>
  45.  
  46.  


tylko jak to teraz zrobić żebyna całej stronie gdzie jest kilka podstron zmieniał się jezyk ?
narazie mam tak:
  1.  
  2. <div class="przyciski_logowania">
  3. <a class="link" href="index.php?strona=en">Angielski</a>
  4. </div>
  5.  
  6. <div class="przyciski_logowania">
  7. <a class="link" href="index.php?strona=pl">Polski</a>
  8. </div>


i ten plik z funkcją muszę includować do każdej podstrony ?
nospor
kluczem twojej tablicy ma nie byc $i tylko key z bazy. Wowczas by dobrac sie do danego klucza robisz poprostu $tablica[$klucz] i juz.
Poza tym pobieranie z bazy mialo byc w funkcji a nie gdzies oddzielnie. Mowilem bys uzyl zmiennej statycznej w funkcji i jesli ona jest pusta to masz pobrac dane z bazy i zapisac do tej tablicy.
djtomaszq
Jak teraz? ...

  1. <?php
  2. function trans($text)
  3. {
  4. static $tablica;
  5.  
  6. if(empty($tablica))
  7. {
  8. require_once "connect.php";
  9. mysqli_report(MYSQLI_REPORT_STRICT);
  10.  
  11. try
  12. {
  13. $polaczenie = new mysqli($GLOBALS['host'], $GLOBALS['db_user'], $GLOBALS['db_password'], $GLOBALS['db_name']);
  14.  
  15. if($polaczenie->connect_errno != 0)
  16. {
  17. throw new Exception($polaczenie->mysqli_connect_errno());
  18. }else
  19. {
  20. $lang = $_GET['strona'];
  21.  
  22. if(!$zapytanie = $polaczenie->query("SELECT klucz, text FROM translate WHERE lang = '$lang'"))
  23. {
  24. throw new Exception($polaczenie->error);
  25. }else
  26. {
  27. while ($wiersz = $zapytanie->fetch_assoc())
  28. {
  29. $tablica[$wiersz['klucz']] = $wiersz['text'];
  30. }
  31. }
  32.  
  33. $polaczenie->close();
  34. }
  35. }catch(Exception $e)
  36. {
  37. echo $e;
  38. }
  39. }
  40.  
  41. return $tablica[$text];
  42. }
  43.  
  44. echo trans('key1')."<br />";
  45. echo trans('key2')."<br />";
  46. echo trans('key3')."<br />";
  47. ?>
  48.  
  49.  
nospor
Coraz lepiej smile.gif

Jeszcze tylko nie tworz do funkcji oddzielnego obiektu bazy danych, tylko przekaz obiekt, ktory juz kiedys tam utworzyles - bo na pewno juz nie raz na stronie utworzyles taki obiekt? Dotyczy to nie tylko tej jednej funkcji ale wszystkiego innego - obiekt bazy danych masz tworzyc tylko raz i przekazywac wszedzie tam gdzie jest potrzebny a nie za kazdym razem tworzysz kolejny obiekt bazy danych
djtomaszq
.. hm czyli jeśli dobrze rozumiem mam plik index.php i tam tylko RAZ tworze połączenie a dalej w tym pliku tylko się odwołuje i mam plik główna.php to też musze RAZ utworzyć obiekt i dalej w tym pliku tylko się odwoływać? Czy może wystarczy w index.php utworzyć obiekt a w główna.php już tylko się odwoływać ?

no ale tej ostatniej rzeczy czyli zrobienie odwołania nie wiem jak się zabrać wiem że chodzi o linijkę
  1. $polaczenie = new mysqli($GLOBALS['host'], $GLOBALS['db_user'], $GLOBALS['db_password'], $GLOBALS['db_name']);

tak? czyli pierwsze tworzenie wyglądałoby tak jak na powyższym skrypcie a kolejne w tym pliku zamiast tej linijki muszę się ("jakoś" bo jeszcze nie wiem jak) się odwołać?

ok, z tym jakoś sobie może poradzę.

.. ale wracając do problemu z tematu zostało mi odwołanie od kliknięcia wyboru języka, mam to teraz zrobione tak:
  1. <div class="przyciski_logowania">
  2. <a class="link" href="pl">Polski</a>
  3. </div>
  4. <div class="przyciski_logowania">
  5. <a class="link" href="en">Polski</a>
  6. </div>


no i z powyższym skryptem działa po kliknięciu tłumaczenie ale mam też inne strony i podstrony na portalu i jak kliknę w menu w inny link i się otworzy inna strona to tłumaczenie znika a nie chce za każdym razem na każdej stronie klikać pl lub en tylko żeby odrazu dla całej witryny tłumaczyło język.

Czy mam to zrobić podczepiając tego $_GET['lang'] do każdego linku na stronie ?
nospor
No mowilem ci na samym poczatku, ze kazdy link ktory generujesz ma zawierac jezyk

Wiec jesli do tej pory generowales link np tak:

<a class="link" href="costam.php">Costam</a>

To teraz ma wygladac tak:
<a class="link" href="costam.php?lang=LANG KTORY AKTUALNIE OBOWIAZUJE">Costam</a>

Zadanie byloby banalnie proste jakbys od samego poczatku uzywal funkcji do generowania linkow, np:

<a class="link" href="<?=linkGenerator('costam')?>">Costam</a>

I funkcja sama za ciebie by dodala teraz jezyk. A ze nie robiles tego to teraz trzeba pocierpiec. Ale nie martw sie, kazdy przez to przechodzil wink.gif
djtomaszq
Ok rozumiem, myślałem linkach ale zrobię to w liście wyboru.

A czy w skrypcie trans ten get jest bezpieczny?
  1. $lang = $_GET['strona'];
  2. if(!$zapytanie = $polaczenie->query("SELECT klucz, text FROM translate WHERE lang = '$lang'")


.. A co do generatora linków pewnie sam tego teraz nie zrobię? biggrin.gif bo w googlach nic nie znalazłem albo źle szukalem
kapslokk
Wpisz se w adresie
?strona=' OR '1
to będziesz wiedział
nospor
Poczytaj o SQLInjection. A skoro uzywasz mysqli to poczytaj o bindowaniu

Co do generowania to zalezy jakie masz linki i czy wszystkie na jeden wzor.
djtomaszq
Linki mam takie
  1. <a href="index.php?strona=podstrona"></a>
i w przyszłości Będzie na pewno coś takiego
  1. <a href="index.php?strona=coś&gra=3&id=1">mecz</a>
  2.  


No i używam przyjaznych linków
nospor
No to twoja funkcja jest banalnie prosta do napisania. Tak na baaaardzo szybko:

  1. function linkGenerator($param) {
  2. $lang = isset($_GET['lang']) ? $_GET['lang'] : 'pl';
  3. if (!in_array($lang, array('pl', 'en'))) {
  4. $lang = 'pl;'
  5. }
  6.  
  7. return "index.php?strona={$param}&lang=$lang";
  8. }
  9.  


A potem w kodzie

<a class="link" href="<?=linkGenerator('podstrona')?>">Costam</a>
<a class="link" href="<?=linkGenerator('strona=cos&gra=3&id=1')?>">Costam</a>
djtomaszq
A czy ma znaczenie jeśli pozamieniam miejscami
?strona=coś&lang=pl
Na
?lang=pl&strona=coś
?
nospor
No widac jakies ma skoro chcesz zamieniac wink.gif
djtomaszq
tylko po to żeby wygladalo tak host.pl/en/strona a nie host.strona/en
czyli język zawsze był pierwszy
nospor
hm, no to teraz mnie zagiales. To albo generujesz index.php?..&...&... albo strona.pl/en/sth. Sie zdecyduj wink.gif
djtomaszq
No nauczyłem się przyjaznych linków i w .htaccess robie przyjazne linki i używam w linku
  1. <a href="zaloguj">Logowanie</a>
  2. <a href="glowna">Strona startowa</a>
  3.  
  4. a w przyszłości
  5. <a href="pl/glowna">Strona startowa</a>
  6. <a href="pl/mecze/1liga">1 liga</a>


ups... facepalmxd.gif
nospor
no to jak zaczniesz uzywac przyjaznych linkow to wtedy zmienisz. Teraz to nie ma znaczenia.
A najlepsze jest to, ze jak juz zrobisz to na tej funkcji to pozniej zmiana na przyjazne linki to bedzie poprawka w tej jednej funkcji a nie w calym projekcie
djtomaszq
No to już w sumie zmieniłem wszystko na przyjazne linki

.htaccess
  1. RewriteEngine On
  2.  
  3. RewriteRule ^([a-z]+)$ index.php?strona=$1


samą funkcje trans mam w osobnym pliku trans.php (czy tak powinno być czy w głównym index.php ją trzymać?)

podstrony includuje przez
  1. SWITCH($_GET['strona'])
  2. {
  3. case "logowanie":
  4. require_once "logowanie.php";
  5. break;
  6.  
  7. case "rejestracja":
  8. require_once "rejestracja.php";
  9. break;
  10.  
  11. case "glowna":
  12. require_once "pliki/glowna.php";
  13. break;
  14.  
  15. case "pl" or "en":
  16. require_once "trans.php";
  17. break;
  18.  
  19. default:
  20. require_once "pliki/glowna.php";
  21. break;
  22. }
nospor
case "pl" or "en":
require_once "trans.php";

A po co ci to?
djtomaszq
To było tylko tak do sprawdzenia czy działa funkcja tłumaczenia osobną stronę zrobiłem do tego ale już to usuwam tego nie ma... smile.gif
nospor
No dobra, ale wtwoim przyjaznym linku brakuje teraz lang a przynajmniej tak wynika z htaccess
djtomaszq
Właśnie do tego doszedłem i widzę problem smile.gif ...
a wszystko przez głupotę bo na szybko sprawdzałem to jako $_GET['strona'] ze wszystkimi innymi podstronami w tym SWITCH.

teraz czy mam zmiane języka robić w przycisku jako..?

  1. <a href="trans.php?lang=pl">Polski</a>


EDIT a linijke w htaccess
  1. RewriteRule ^([a-z]+)/([a-z]{2})$ index.php?strona=$1&lang=$2


EDIT 2: Czy może być tak?

Linki do zmiany języka:
  1. <div class="przyciski_logowania">
  2. <a class="link" href="test-en">Angielski</a>
  3. </div>
  4.  
  5. <div class="przyciski_logowania">
  6. <a class="link" href="test-pl">Polski</a>


EDIT 2: Czy może być tak?

Linki do zmiany języka:
  1. <div class="przyciski_logowania">
  2. <a class="link" href="test-en">Angielski</a>
  3. </div>
  4.  
  5. <div class="przyciski_logowania">
  6. <a class="link" href="test-pl">Polski</a>


EDIT 2: Czy może być tak?

Linki do zmiany języka:
  1. <div class="przyciski_logowania">
  2. <a class="link" href="test-en">Angielski</a>
  3. </div>
  4.  
  5. <div class="przyciski_logowania">
  6. <a class="link" href="test-pl">Polski</a>


.htacces
  1. RewriteRule ^([a-z]+)-([a-z]{2})$ index.php?strona=$1&lang=$2


i funkcję trzymam samą w pliku trans.php a require_once dołączam go na górze do index.php

Czy tak będzie dobrze?

EDIT 3: a robię tak: test-en zamiast test/en bo wtedy psuje mi css'a i nie pamiętam jak to naprawić
nospor
Nie zadne test-en tylko test/en a najlepiej by jezyk byl pierwszy czyli en/test

Co do problemu z css i js to sciezki do css daje sie pelne a nie niepelne - temu ci nie dziala
Nie: style.css
tylko: http://mojastrona.pl/style.css
Od biedy: /style.css
djtomaszq
Ok wszystko fajnie działa tylko jak wchodzę na stronę tak: localhost/mojastrona to wyskakuje błąd że nie ma zmiennej GET. Klikając linki to już wszystko działa tylko przy tym pierwszym zalogowaniu jest błąd. Czy wystarczy jak.do index.php dodam że jeśli nie istnieje $_GET['lang'] to przypisuje jej 'pl'?
SwiezuPL
Cytat(djtomaszq @ 5.07.2016, 22:48:10 ) *
Ok wszystko fajnie działa tylko jak wchodzę na stronę tak: localhost/mojastrona to wyskakuje błąd że nie ma zmiennej GET. Klikając linki to już wszystko działa tylko przy tym pierwszym zalogowaniu jest błąd. Czy wystarczy jak.do index.php dodam że jeśli nie istnieje $_GET['lang'] to przypisuje jej 'pl'?

... albo jeśli taka zmienna nie istnieje przekieruj na adres tylko że z zmienną get o danej wartości.
nospor
Przeciez w kodzie dalem sprawdzanie czy zmienna w get istnieje czy nie
$lang = isset($_GET['lang']) ? $_GET['lang'] : 'pl';

cos mnie wacpan sciemniasz wink.gif
djtomaszq
Ja nie, chyba że mój kod... sciana.gif

index.php (fragment)
  1. <?php
  2.  
  3. require_once "connect.php";
  4. require_once "trans.php";
  5.  
  6. $http = 'http://localhost/strona';
  7.  
  8. if(!isset($_GET['strona']))
  9. {
  10. $_GET['strona'] = "";
  11. }
  12.  
  13.  
  14.  
  15. function linkGenerator($param)
  16. {
  17. global $http;
  18.  
  19. $lang = isset($_GET['lang']) ? $_GET['lang'] : 'pl';
  20. if (!in_array($lang, array('pl', 'en'))) {
  21. $lang = 'pl';
  22. }
  23.  
  24. return "$http/{$param}/$lang";
  25. }
  26. ?>
  27. <!DOCTYPE HTML>
  28. <html lang="pl">


i wtedy jak wpsze: localhost/strona/
to wyswietla:
  1. Notice: Undefined index: lang in C:\xampp\htdocs\strona\trans.php on line 22


a jak dodam do index.php
  1. if(!isset($_GET['lang']))
  2. {
  3. $_GET['lang'] = "pl";
  4. }

To działa i błędu nie ma
nospor
A co ty mi index.php pokazujesz jak blad wyraznie mowi ze to trans.php.... czytaj uwaznie komunikaty bledow,

Do trans tez masz dodac tem kawalek kodu
$lang = isset($_GET['lang']) ? $_GET['lang'] : 'pl';
if (!in_array($lang, array('pl', 'en'))) {
$lang = 'pl';
}

A nalepiej jezyk masz ustalac w jednym miejscu i przekazywac gdzie trzeba
djtomaszq
jak dodam ten kawałek do trans.php to dalej ten sam błąd

linijka błędu w trans.php
  1. $lang = mysqli_real_escape_string($polaczenie, $_GET['lang']);
nospor
skoro LANG po moim kodzie znajduje sie w $lang to masz go juz nie szukac w $_GET['lang']...

rozumiesz w ogole co robi ten kod
$lang = isset($_GET['lang']) ? $_GET['lang'] : 'pl';
if (!in_array($lang, array('pl', 'en'))) {
$lang = 'pl';
}

?
Bo jesli nie to usiadz nad nim na 5 minut i go przeanalizuj bo latasz teraz z totalnymi podstawami.
djtomaszq
Tak, wiem co on oznacza tylko że bez tej linijki dalej jest błąd

  1. Notice: Undefined [b]variable[/b]: lang in C:\xampp\htdocs\strona\trans.php on line 29


tym razem w tej linijce
  1. if(!$zapytanie = $polaczenie->query("SELECT klucz, text FROM translate WHERE lang = '$lang'"))
nospor
To mi juz na dzisiaj wystarczy. Przeczytaj jeszcze raz moich pare ostatnich postow i zastanow sie nad nimi dluzej bo ewidentnie gubisz bardzo istotny a zarazem prosty fakt.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.