Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: global czy referncja czy...?
Forum PHP.pl > Forum > PHP
be2k
witam

w projekcie uzywam smarty i m.in. PEARowskiej klasy MDB2 do oslugi bazy danych.
pozatym napisalem kilka klas i w niektorych z nich potrzebuje obiektu $smarty i/lub $mdb2.
ktore z nastepujacych rozwiazan bedzie najlepsze pod wzgledem wydajnosci?:

1) uzywam instrukcji global w konstruktorze klasy i przypisuje obiekty $smarty i $mdb2 do wlasciwosci $this->smarty i $this->mdb2 danej klasy
  1. <?php
  2. $smarty = new Smarty();
  3. $mdb2 =& MDB2::connect($CONFIG['db']['dsn']);
  4.  
  5. $objClass1 = new Class1()
  6. $objClass2 = new Class2()
  7. itd.
  8.  
  9. //a w klasach
  10. class Class1 //Class2 itd...
  11. {
  12. private $smarty;
  13. private $mdb2;
  14.  
  15. function __construct()
  16. {
  17. global $smarty;
  18. global $mdb2;
  19. $this->smarty=$smarty;
  20. $this->mdb2=$mdb2;
  21. //i juz w innych metodach uzywam $this->smarty i $this->mdb2
  22. }
  23. }
  24. ?>


2) przekazuje obiekty $smarty i $mdb2 przez referencje do konstruktora danej klasy i tam przypisuje je do wlasciwosci $this->smarty i $this->mdb2 danej klasy
  1. <?php
  2. $smarty = new Smarty();
  3. $mdb2 =& MDB2::connect($CONFIG['db']['dsn']);
  4.  
  5. $objClass1 = new Class1($smarty,$mdb2)
  6. $objClass2 = new Class2($smarty,$mdb2)
  7. itd.
  8.  
  9. //a w klasach
  10. class Class1 //Class2 itd...
  11. {
  12. private $smarty;
  13. private $mdb2;
  14.  
  15. function __construct(&$smarty,&$mdb2)
  16. {
  17. $this->smarty=$smarty;
  18. $this->mdb2=$mdb2;
  19. //i juz w innych metodach uzywam $this->smarty i $this->mdb2
  20. }
  21. }
  22. ?>


3) w konstruktorze danej klasy tworze obiekty $smarty i $mdb2 i przypisuje je do wlasciwosci $this->smarty i $this->mdb2 danej klasy
  1. <?php
  2. $objClass1 = new Class1()
  3. $objClass2 = new Class2()
  4. itd.
  5.  
  6. //a w klasach
  7. class Class1 //Class2 itd...
  8. {
  9. private $smarty;
  10. private $mdb2;
  11.  
  12. function __construct()
  13. {
  14. global $CONFIG;
  15. $this->smarty = new Smarty();
  16. $this->mdb2 =& MDB2::connect($CONFIG['db']['dsn']);
  17. //i juz w innych metodach uzywam $this->smarty i $this->mdb2
  18. }
  19. }
  20. ?>


sa jeszcze dwie opcje:
4) tak jak w 1) tylko instrukcji global uzywam w METODZIE ktora takiego obiektu potrzebuje a nie w konstruktorze, wiec nie tworze wlasciwosci $this->smarty i $this->mdb2, wiec jak dobrze rozumuje obiekt nie ma takich wlasciwosci == jest mniejszy (?)
5) tak jak w 2) ale obiekty smarty i mdb2 przekazuje normalnie nie przez referencje &

ps. w tych klasach tez potrzebuje np. zmiennej $CONFIG w ktorej mam ustawienia konfiguracyjne, wiec to co wyzej opisalem tyczy sie nie tylko obiektow ale takze zwyklej zmiennej.

z gory dziekuje za odpowiedz
kosmowariat
zdecydowanie przez referencję
ad .1. global wymaga zmiennej o określonej nazwie tzn że powiedzmy masz w funkcji global $smarty a w wykorzystującym ponownie projekcie/skrypcie obiekt typu smarty nazwiesz sobie np $template i lipa...

ad.2. masz mały błąd - mianowicie przypisanie przez referencję wykonuje się poprzez &
  1. <?php
  2. $objClass1 = new Class1(&$smarty,&$mdb2);
  3. $objClass2 = new Class2(&$smarty,&$mdb2);
  4. ?>


ad.3. załóżmy sytuację że tworzysz jakieś 2 obiekty: $obj1 i $obj2 i wykonujesz jakieś metody w każdym z poszczególnych obiektów i chciałbyś wszystko wyświetlić w jednym szablonie....
  1. <?php
  2. //tworzymy obiekty etc
  3. $obj1->metoda(); //następuje przypisanie jakichś zmiennych do smarta
  4. $obj2->metoda(); //j.w
  5. // i jak to teraz wyświetlić ...?
  6. ?>

rozwiązaniem jest połączenie szablonu z najwyżej jednym obiektem

ponownie ad2
  1. <?php
  2. $smarty = new smarty()
  3. //ustawienie parametrów smarta
  4. $obj1 = new Class1(&$smarty,&$mdb2);
  5. $obj2 = new Class2(&$smarty,&$mdb2);
  6. $obj1->metoda(); //następuje przypisanie jakichś zmiennych do smarta
  7. $obj2->metoda(); //j.w
  8.  
  9. $smarty->display('cos.tpl');
  10. ?>
be2k
dzieki za odpowiedz, ale nie do konca o to mi chodzilo.

wszystkie te "niedogodnosci" o ktorych napisales oczywiscie moge stanowic problem, ale tylko w konkretnym przypadku. nie jestem w stanie opisac calego projektu ktory robie, moge tylko opisac waskie zagadnienie co do ktorego mam watpliwosci lub chce cos wyjasnic, a wlasnie w moim projekcie te rzeczy o ktorych napisales nie beda stanowily problemu, bo np. wiem zawsze jaka nazwe bedzie miala zmienna wiec global bedzie ok, metody ktore potrzebuja obiektu $smarty zwracaja HTML'a ($smarty->fetch()) wiec ten problem tez odpada itd.

chodzi mi tylko i wylacznie o to ktory z tych sposobow jest najbardziej wydajny

PS. co do przypadku drugiego to wlasnie gdzies czytalem (nie wiem czy to chodzilo ogolnie, czy tylko o PHP5) ze znak referencji & powinno sie umieszczac w deklaracji funkcji a nie w wywolaniu, czyli tak jak napisalem.
kwiateusz
w php5 wszystko jest przekazywane przez referencje domyślnie...
EuReKa
Sugerowałbym global w każdej metodzia która wymaga danych zmioennych. gloabal jest równoważny referecncji.
Cytat(be2k @ 25.07.2007, 17:00:02 ) *
PS. co do przypadku drugiego to wlasnie gdzies czytalem (nie wiem czy to chodzilo ogolnie, czy tylko o PHP5) ze znak referencji & powinno sie umieszczac w deklaracji funkcji a nie w wywolaniu, czyli tak jak napisalem.

Masz rację.
Cytat
w php5 wszystko jest przekazywane przez referencje domyślnie...

Wszystkie obiekty. W PHP przekazywanie przez referencję jest wolniejsze, niż bez. PHP nie kopiuje zmiennej dopóki nie będzie zmieniona jej wartość ("just in time").
kwiateusz
Nie zrozumiałem tego zdania dlaczego referencja jest wolniejsza... Referencja zapobiega kopiowaniu obiektu więc jak może być wolniejsza jak operuje już na raz stworzonym obiekcie.

O globalach, singletonie itp już jest jeden watek możesz sie zapoznać w celu pogłębienia wiedzy, ale moje zdanie to takie ze lepiej w konstruktorze przekazać te 2 obiekty aby zachować hermetyzacje klasy niz ja burzyć globalami.
EuReKa
Cytat(kwiateusz @ 25.07.2007, 18:26:01 ) *
Nie zrozumiałem tego zdania dlaczego referencja jest wolniejsza... Referencja zapobiega kopiowaniu obiektu więc jak może być wolniejsza jak operuje już na raz stworzonym obiekcie.

W PHP5 kopiować obiekty można tylko przy użyciu clone. W każdym innym przypadku dostajemy referencje do obiektu. Z innymi zmiennymi jest nieco inaczej. Gdy zmienna jest przekazywana jako argument funkcji, PHP nie kopiuje wartości zmiennej. Robi to dopiero, gdy zmienna zostaje nadpisana. Gdy używamy referencji, a zmiennej PHP tworzy tą referencje zupełnie niepotrzebnie (chyba, że faktycznie zmieniamy wartość tej zmiennej). Analizator kodu Zenda wyłapuję takie niepotrzebne referencję.
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.