Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: PHP OOP i strona wielojęzyczna
Forum PHP.pl > Forum > PHP
szczypior

index.php
  1. include 'classes/lang.class.php';
  2.  
  3.  
  4. $lang = new lang_set($_GET['lang']);
  5.  
  6. include_once 'lang/'.$lang;


plik lang.class.php
  1. <?php
  2. class lang_set{
  3.  
  4. private $lang;
  5.  
  6. public function __construct($lang_in){
  7.  
  8. // gdy mamy zmienną, to znaczy że użytkownik chce zmienić obecny język
  9. If(!empty($lang_in))
  10. {
  11.  
  12. switch ($lang_in) {
  13. case 'en':
  14. $this->lang = 'en';
  15. break;
  16.  
  17. case 'pl':
  18. $this->lang = 'pl';
  19. break;
  20.  
  21. default:
  22. $this->lang = 'pl';
  23. }
  24. $_SESSION['lang'] = $lang;
  25. setcookie('lang', $lang, time() + (3600 * 24 * 30));
  26. }
  27. else if(isSet($_SESSION['lang']))
  28. {
  29. //gdy mamy zmienną sesyjną, to ją odczytujemy
  30. $this->lang = $_SESSION['lang'];
  31. }
  32. else if(isSet($_COOKIE['lang']))
  33. {
  34. // gdy użytkownik ma ciasteczko to odczytujemy zapisany w nim język i zapisujemy dodatkowo do zmiennej sesyjnej
  35. $this->lang = $_COOKIE['lang'];
  36. $_SESSION['lang'] = $_COOKIE['lang'];
  37. }
  38. else
  39. {
  40. //domyślny język
  41. $this->lang = 'pl';
  42. }
  43. }
  44.  
  45. public function __toString()
  46. {
  47. return $this->lang.'.lang.php';
  48. }
  49. }
  50. ?>
nospor
Komentarze zaczyna sie poprzez
//
a nie
'

Twoj kod z obiektowka nie ma zadnego zwiazku - przenosze.

Trzymanie jezyka w sesji czy w ciachu to nieporozumienie. Jezyk ma byc w url, najlepiej w ladnym url.
I tak strona pl moze wykladac tak:
http://mojastrona.pl/

zas wersja angielska juz tak:
http://mojastrona.pl/en/

Odpalaj swoj kod na wlaczonym wyswietlaniu wszystkich bledow

ps:
'lang/pl.lang.php'
czy naprawde plik z jezykiem, ktory lezy w katalog LANG musi miec jeszcze sufix LANG? Czyz nie jest to dosc oczywiste z faktu ze lezy w katalogu LANG i ma nazwe PL czy EN ?
szczypior
Dzięki za opinię.

Dlaczego uważasz, że nie jest on w ogóle obiektowy? Co powinienem zmienić, żeby go "uobiektowić"?
nospor
Wsadzenie kawalka kodu w klase, a tak naprawde w konstruktor, nie czyni z niego OOP tylko poprostu kod w klasie wink.gif
szczypior
Czego brakuje temu kodowi, by faktycznie był obiektowy?

Wszystko jest w konstruktorze, bo ta klasa wydawała mi się na tyle mało rozbudowana, że nie potrzebuje dodatkowych funkcji. Jak mniemam, myliłem się smile.gif

Będę bardzo wdzięczny za sugestie smile.gif

Abstrahując od tego, że faktycznie zmianę języka można rozwiązać w lepszy sposób (tak jak sugerujesz przez htaccess), to czy możesz wskazać kierunek, jak należałoby poprawić ten kod, by stał się obiektowym.
Czy właśnie należałoby go podzielić na funkcje?

Z góry dzięki za odpowiedź smile.gif
nospor
Wybacz, moze troche wprowadzilem cie w blad.
OOP - Object Oriented Programming
W dziale OOP zajmujemy sie (a przynajmniej powinnismy) troche bardziej powazniejszymi sprawami jak klasa, ktorej jedyne zadanie to ustawienie jezyka na podstawie parametru w GET. To z OOP nie ma o tyle zwiazku, ze tutaj zastosowanie klasy nic nie w nosi. Od kod strukturalny wlozyles w klase. Zasadza dzialania kodu sie nie zmienila.

Na chwile obecna masz klase, masz obiekt - starasz sie pisac obiektowo a nie strukturalnie - to juz cos.

Nie mniej jednak wypadaloby sie troche zapoznac z roznymi konwencjami, np PSR i nazewnictem klass i plikow klas.
Ot prosty przyklad:
Twoj plik z klasa nazywa sie lang.class.php a sama klasa lang_set
1) wyrzuc class z nazwy pliku
2) Plik ma sie nazywac tak samo jak klasa
3) plik Lang.php, klasa Lang

Jak zaczniesz lekture PSR to wpadniesz na cos takiego jak autoload - przydatne cudo wink.gif
viking
W samej klasie masz co najmniej kilka funkcjonalności. Pierwsze to przekazanie i odczyt wartości języka. Tu dodatkowo jeśli byś miał 20 języków to taki switch mocno by sie rozrosł. Nie można z tej klasy wyciągnąć bieżącej wartości języka. Drugi to adapter storage który akurat jest sesją domyślną ale gdybyś chciał zmienić na jakiś komponent zewnętrzny wtedy cały kod jest do przepisania a nie tylko dany fragment. Dodatkowo na sztywno czas sesji którego nie można zmienić przez konfigurację. O fatalnym nazewnictwie nospor już pisał.
kpt_lucek
  1. class Lang
  2. {
  3. /** @var LangResolverInterface */
  4. protected $langResolver;
  5.  
  6. /** @var string */
  7. protected $lang;
  8.  
  9. /**
  10. * Lang constructor.
  11. *
  12. * @param LangResolverInterface $langResolver
  13. */
  14. public function __construct(LangResolverInterface $langResolver)
  15. {
  16. $this->langResolver = $langResolver;
  17. $lang = $langResolver->getDefaultLang();
  18. }
  19.  
  20. /**
  21. * @param string $lang
  22. *
  23. * @return $this
  24. */
  25. public function changeLang($lang)
  26. {
  27. $resolvedLang = $this->langResolver->resolve($lang);
  28. if (null === $resolvedLang) {
  29. throw new \InvalidArgumentException(sprintf('Lang "%s" is not supported.', $lang));
  30. }
  31. $this->lang = $resolvedLang;
  32.  
  33. return $this;
  34. }
  35. }


Możesz coś podobnego przekminić, wydziel logikę odpowiedzialną za "sprawdzenie" języka gdzieś na zewnątrz, dispatchuj event na zmianę języka.

Opcji są miliony

Cytat
gdy użytkownik ma ciasteczko to odczytujemy zapisany w nim język i zapisujemy dodatkowo do zmiennej sesyjnej

Wywal to do osobnego obiektu, który w razie potrzeby odpali
  1. ->setLang($lang);
na klasie Lang, z założenia Lang nie musi wiedzieć kto, skąd i po co zmienia język, ma to tylko ogarnąć po swojej stronie i tyle (plus ewentualnie powiadomić jakimś eventem że zmiana miała miejsce)

Cytat
gdy mamy zmienną, to znaczy że użytkownik chce zmienić obecny język

Może abstrakcja, ale... co jeżeli pewna część kontentu będzie w innym języku? W teorii muszę utworzyć nową instancję klasy Lang po to, żeby w tym momencie ten język zmienić?

Cytat
  1. return $this->lang.'.lang.php';

Może potraktuj tłumaczenia (zakładam strukturę key=>value) raczej jako config? W sensie *.ini, *.yml, xml itd.
Dodatkowo, możesz napisać sobie coś w rodzaju Translatora, co za tym idzie... mówić mu aby tłumaczył klucze na uprzednio załadowanej konfiguracji języka.
Do tego musisz oczywiście pamiętać o fallback'u - w momencie gdy dane tłumaczenie (klucz) nie istnieje.


P.S. taki troche Symfony-way
IAmBoskiM
  1. else if

questionmark.gifquestionmark.gifquestionmark.gifquestionmark.gifquestionmark.gif
To nie JS.

  1. elseif ($warunek) {
  2. }
  3. // albo
  4. else {
  5. if ($warunek) {
  6. }
  7. }


@Down Huh, no rzeczywiście. Myślałem, że to zawsze jest błąd. Ale osobiście i tak odradzam stosowanie tego jako dwa słowa, bo przy klamrach działa, a przy dwukropkach nie, a elseif działa przy wszystkim.
Comandeer
No to przecież else if jest równoznaczny z Twoim drugim kodem bez klamerek → http://php.net/manual/pl/control-structures.elseif.php
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.