Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php] zmienne globalne, tablica $GLOBALS
Forum PHP.pl > Forum > PHP
jml
Mam takie pytanie.

Od jakiegoś czasu w swoich skryptach używam takiego wzorca. Mając pliki z klasami, tworzę plik objects.php, w nim po jednym egzemplarzu danego obiektu.

Objects.php dołączam do index.php, i tym sposobem we wszystkich skryptach, kiedy chcę się odwołać do danego obiektu, nie tworzę jego nowej instancji, a odwołuję się poprzez przykładowo:
  1. <?php
  2. $GLOBALS['obiekt']->metoda();
  3. ?>

gdyż w index.php mielą się wszystkie skrypty.

Zastanawiam się ostatnio nad zaletami i wadami takiego sposobu, gdyż zmiennych globalnych powinno się raczej unikać. Co myślicie o takiej praktyce? Czy zmienić ją i za każdym razem tworzyć instancję obiektu tam, gdzie to jest potrzebne? Jak to się ma do wydajności?
phpion
Twórz obiekty tylko wtedy, gdy będą Ci potrzebne. Z Twojego postu wnioskuję, że w objects.php tworzysz wszystkie obiekty, które występują w systemie. Moim zdaniem rozwiązanie nie najlepsze. Po co tworzyć obiekty, z których i tak nie skorzystasz? Zdecydowanie lepiej powoływać je do zycia tylko wtedy, gdy chcesz z nich skorzystać.
nospor
Zainteresuj sie wzorcami projektowymi:
Rejestr oraz Singleton
jml
Obaj macie rację.

Inny przykład. Mam klasę database, przy tworzeniu obiektu nawiązywane jest połączenie do bazy, przy usuwaniu jest zamykane. Obiekt ten powinien więc najlepiej istnieć jako jeden egzemplarz i przez cały czas trwania skryptu. Idealne do zastosowania wzorca Singleton?

I jeszcze jedno, do wywoływania zapytań muszę używać tego obiektu. I teraz, czy:

1.) Wywoływać go wszędzie globalnie, tzn:
  1. <?php
  2. $GLOBALS['dbObj']->query($q);
  3. ?>


2.) Do każdej klasy, korzystającej z bazy, przekazuję referencje do obiektu bazy i posługuję się tą referencją (w php5 domyślnie):
  1. <?php
  2. class Sample
  3. {
  4. private $db;
  5. function __construct($dbObj)
  6. {
  7. $this->db = $dbObj;
  8. }
  9. }
  10. ?>

wtedy wywołuję:
  1. <?php
  2. $this->db->query($q);
  3. ?>


Który sposób wybrać? Skłaniałbym się ku drugiemu ale wolę zapytać, bo czy w tym przypadku nie byłoby dobrze korzystać z $GLOBALS, skoro i tak obiekt bazy muszę mieć praktycznie wszędzie?
cbagov
Po co ci ten Singleton jak wywolanie polaczenia bez dodatkowego parametru i tak bedzie w PHP tym samym polaczeniem.
A "klasa korzystajaca z bazy" = co, klasa, ktora korzysta z danych czy klasa, ktora pracuje na bazie - wniosek jest automatyczny.
jml
Pytam się po prostu co lepiej używać, które rozwiązanie jest efektywniejsze.

Co z tego że wszędzie mam otwarte połączenie? Nie walę przecież wszędzie mysql_query, poźniej nie sprawdzam czy zwróciło coś i nie jadę wiersz po wierszu z fetch_assoc, wywołuję tylko funkcję query() na obiekcie klasy database, która mi zwraca tablicę z wszystkimi rekordami i po bólu. Co mi po tym że połączenie otwarte, muszę się jakoś do tej funkcji odnieść.

Klasa korzystająca z bazy - klasa, która pracuje na danych pobieranych z bazy.
cbagov
@"Co z tego że ..."
To, ze Singleton nie potrzebuje miec zwiazku z -connect- w PHP i o tym mowie, a tym bardziej ze zmieniajacymi sie danymi z bazy, bo chyba nie bedzie ona nieedytowalna.

@"Klasa korzystająca ..."
Skoro tylko pracuje na danych, moze a nawet powinna byc kompletnie oddzielona od SQL dla zapewnienia modulowosci.

Przyda sie w C, Javie czy w ... PHP np dla obslugi jakiegos konfiga, ale jak juz gdzies pisalem, wtedy, kiedy pracujesz w grupie albo udostepniasz kod, jak nie, to nie marnuj czasu na rozwiazywanie mozliwych konfliktow spowodowanych naduzyciami tego wzorca.
jml
Cytat
Często w aplikacji istnieje potrzeba stworzenia klasy, która posiadałaby wyłącznie jedną instancję. Zwykle związane to jest z zapewnieniem większej wydajności aplikacji, np. przy dostępie do bazy danych, gdzie każde łączenie się z bazą jest dla aplikacji kosztowne, bo wymaga czasochłonnego uwierzytelnienia i autoryzacji. W tym przypadku sensowniej jest stworzyć jeden obiekt przechowujący sesję połączenia i wykorzystać go do przesłania wielu zapytań.

źródło: http://pl.wikipedia.org/wiki/Wzorzec_singletonu

Czyli jednak wzorzec ten nadaje się tutaj. Poza tym po co wywoływać za każdym razem connect? Co z tego że zwróci nam już to otwarte, lepiej mieć po prostu np uchwyt do tego połączenia od razu, np w obiekcie. I co ma singleton do zmieniających się danych z bazy?

Jak rozumiesz kompletne oddzielenie od SQL?

  1. <?php
  2. $q = "SELECT coś tam";
  3. $resultTab = $dbObj->query($q);
  4. ?>

Tak nie wystarczy? Gdzieś musi być zapytanie, tak czy tak. W istocie w klasie mam tablicę z danymi, ale skądś te dane muszą się w niej wziąć. Powiedz mi jak tu można wydzieliś SQL.
cbagov
Kod
po co wywoływać za każdym razem connect?


Ja nie mowilem o wywolywaniu connect tylko o zaniechaniu singletona, to dwie rozne sprawy.
Po prostu skoro php troszczy sie o JEDNO polaczenie, nie ma sensu akurat singletona angazowac do tego celu.
Takze formulka z wiki jest ogolna a nie zwiazana z tym aspektem PHP.

MOZESZ go zastosowac, tylko pytam po co, to jak zakladanie kasku w domu bo moze walniesz w futryne idac do WC - twoj wybor.

Robisz Obiekt od zarzadzania SQL, ktory zajmuje sie tym wszystkim o czym wiesz, polaczenie *(cytat), logowanie i fetche i inne.

A obiekt z danymi to DANE, dzis beda obrabiane na SQL a juto na czym innym wiec wiazac ich z SQL nie ma po co.

Obiekt sql pobiera dane dla obiektow obrabiajacych i zadne powiazanie nie jest konieczne, dzieki temu masz mozliwosc latwego tworzenia modulow, pluginow etc. co znowu nie oznacza, ze nie mozna zawrzec tej opcji w 1 obiekcie, zeby nie bylo ze cos pominalem hehe.
Pewnych rzeczy po prostu nie pisze skoro nie sa potrzebne.
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.