Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][REDIS] Wykorzystywanie klienta Redis w projekcie
Forum PHP.pl > Forum > PHP
tadeurz
Mam problem wynikający z braku doświadczenia. Już wcześniej się z nim spotykałem ( nie warto pisać jak go rozwiązywałem) teraz chciałbym dowiedzieć się jak to powinno być implementowane.
Problem dotyczy prawie każdej bazy danych, bo do każdej stworzona jest klasa do obsługi(API -> PDO, MongoClient, Predis ).
I teraz pytanie brzmi jak tego używać ? W przykładzie posłużę się Predis.
https://github.com/nrk/predis
  1. //przykładowy kod index.php
  2. Predis\Autoloader::register();
  3. ...
  4. $redis = new Predis\Client();
  5. $redis->get(variable);
  6. ...//tutaj peracje na $redis
  7. $user = new user();
  8. class user(){
  9. function __construct(){
  10. $id = $_SESSION[user];
  11. //zmieniliśmy środowisko i zmienna $redis jest tutaj niedostępna
  12. //tutaj chce pobrać z Redis wartość która kryje się pod kluczem $id;
  13. $redis = new Predis\Client(); //niestety muszę tworzyć nową instancje
  14. $this->userName = $redis->get($id);
  15. }
  16. }

Rozwiązanie w którym w każdym miejscu gdzie będę chciał użyć redis muszę tworzyć nową instancje redis wydaje mi się dziwne. Każda z takich bibliotek powinna być obudowana własną która implementuje daną bibliotekę jako singleton ?

Nie potrzebuje dokładnej odpowiedzi jak to powinno być zrobione.
Np wystarczy mi wasze doświadczenie. Jak wy używacie PDO ?
Wazniak96
Podaj obiekt bazy danych jako argument do konstruktora klasy i utwórz z niego prywatny obiejt tej klasy.

Czyki przykładowo;
  1. $db = new PDO(); //w skrucie...
  2.  
  3. $user = new user($db);
  4.  
  5. class user
  6. {
  7. private $db;
  8.  
  9. function construct($db)
  10. {
  11. $this->db = $db;
  12. }
  13. }
tadeurz
Tak mogę tak zrobić.
W takim przypadku w konstruktorze każdej klasy wymagającej $redis musiałbym dodawać argument, lub dziedziczyć tą klasę z klasy gdzie ten obiekt jest już dostępny. tiredsmiley.gif

Do tej pory najbardziej przekonany jestem do zrobienia z $redis obiektu globalnego.
Wazniak96
Singleton też nie jest złym rozwiązaniem z tego co się orientuję.

Tutaj nie ma co marudzić tylko przerabiać jeżeli chce się mieć poprawnie.
Daiquiri
To czy zrobisz to za pomocą wstrzykiwania (z wykorzystaniem metody, atrybutu lub przez konstruktor) czy jak wspomniano sprawisz, że klasa dla której wywołujesz nową instancję najpierw sprawdzi czy już takiej nie ma, żeby ją zwrócić - nie jest istotne.... bo zawsze będzie to lepsze od obiektu globalnego wink.gif.

Nie znam całej apki, ale przecież nie wszędzie potrzebujesz dostępu do $redis no i często klasy logiki i tak dziedziczą.

No i przede wszystkim: Temat: Jak poprawnie zatytulowac watek
tadeurz
Czyli:
-> GLOBAL jest złym pomysłem, jak zawsze zresztą biggrin.gif
-> tworzenie nowej instancji obiektu za każdym razem też jest złe $redis

Wstrzyknięcie $redis to jakiegoś commonAction/commonModel to dobry pomysł.
Daiquiri
Wstrzyknięcie lub po prostu tworzysz coś na kształt:
Kod
if (nie mam własnej instancji)
{
    stwórz instancję;  
    zapisz ją do statycznego atrybutu $redis;
    zwróć $redis;
} else
{
    zwróć $redis;
}
dla klasy typu redis z prywatnym konstruktorem (żebyś się przypadkiem nie zagalopował) i statyczną metodą + statycznym atrybutem $redis, w którym przechowujesz instancję.

Wtedy z każdym wywołaniem klasy redis nie stworzysz nowego obiektu (bo nie jest to możliwe) i dostaniesz ten sam. Możesz to organizować w kontenerach lub nie, w zależności od potrzeb.
tadeurz

Pod dłuższym zastanowieniu i próbie przelania tego na kod nie pozostaje nic innego jak zrobić z tego to o czym Ty piszesz : singleton. A forma jego wstrzyknięcia pozostaje do wyboru.
Mylę się czy zdanie w pierwszym poście jest bardzo dobrym spostrzeżeniem/radą ?

Cytat(tadeurz @ 20.07.2013, 21:41:09 ) *
Rozwiązanie w którym w każdym miejscu gdzie będę chciał użyć redis muszę tworzyć nową instancje redis wydaje mi się dziwne. Każda z takich bibliotek powinna być obudowana własną która implementuje daną bibliotekę jako singleton ?
Daiquiri
Nie wiem za bardzo co masz na myśli w tym zdaniu smile.gif. Jeżeli klasę redis masz już podpiętą, to nie musisz jej nigdzie wstrzykiwać. W klasie, w której jest potrzebna wywołujesz np. redis::getInstance() i jako zwrot otrzymujesz instancję.
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.