Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Singletony w PHP 4
Forum PHP.pl > Forum > PHP > Pro > Archiwum Pro
seaquest
No cóż. Staram się napisać uniwersalny kod (dla php4 i php5), oczywiście piszę obiektowo i chciałbym użyć singletonów. I w związku z tym moje pytanie: Jak rozwiązujecie problem singletonów w php 4?

Pytanie zadaję w osobnym topicu, ponieważ w wielu tematach jest to poruszane, ale nie rozwiązywane. Myślę, że jeśli zgromadzimy tutaj wszystkie kody/odpowiedzi, to może ktoś stworzy naprawdę dobry kod kontrolujący liczbę instancji w aplikacji smile.gif

Czekam na rozwiązania...
halfik
Generalnie to piszę póki co sturkturalnie, ale gdybym w 4 miał zrobić singletona, to wykorzystałbym w tym celu zmieną globalną, a w klasie kontrolował jej wartość. W konstruktorze naturalnie inkrementowałbym zmienną i nie pozwolił tworzyć obiektu, jeśli ma ona wartość 1 (początkowa naturalnie 0). To tak czysto teoretycznie, bo nie sprawdzałem...
rzseattle
Najlatwiej jest uzyc zmiennej statycznej:
  1. <?php
  2. function &singleton() {
  3. static $instance;
  4. if (!isset($instance)) {
  5. $instance = new klasa;
  6. }
  7. return $instance;
  8.  }
  9. ?>
seaquest
rzseattle: prawdę mówiąc to ten kod (mnie przynajmniej) w php4 nie działa mimo że wywołuję metodę singleton poprzez
  1. <?php klasa::singleton(); ?>
halfik
W JAVA zrobiłbym to tak:

class Test{
private Test(){}
public static Test makeTest(){
return new Test();
}
private static Test t1 = new Test();
public static Test access(){
return t1;
}
}

A później już tylko:

Test myTest = Test.makeTest();
FiDO
Podczas moich prob dojscia do tego jak sie je stosuje w php4 (bylo kilka problemow z referencjami) powstal taki oto testowy kod:
  1. <?php
  2.  
  3. class Singleton {
  4. var $var;
  5.  
  6. function Singleton()
  7. {
  8. echo &#092;"Singleton::Singleton();<br>\";
  9. }
  10.  
  11. function &Get()
  12. {
  13. static $inst = NULL;
  14.  
  15. if ($inst == NULL)
  16. $inst = new Singleton;
  17.  
  18. return $inst;
  19. }
  20. }
  21.  
  22.  
  23. $a = &Singleton::Get();
  24. $a1 = &Singleton::Get();
  25. $a2 = &Singleton::Get();
  26. $a->var = 99;
  27. var_dump($a, $a1, $a2);
  28.  
  29. $b = &Singleton::Get();
  30. $a->var = 1;
  31. $c = &Singleton::Get();
  32.  
  33. ?>


Mysle, ze to wszystko wyjasnia...
halfik
A ja myślę, że to nie jest taki całkiem singleton, bo w tym wzorcu konstruktor MUSI być prywatny, bo jak inaczej chesz wymusić na programiście-kliencie używanie jakiejś metody do towrzenia instancji klasy? A tak robisz prywatny konstruktor i klasa sama w sobie tworzy obiekt i zwraca referencję do niego.
hawk
Cytat
A ja myślę, że to nie jest taki całkiem singleton, bo w tym wzorcu konstruktor MUSI być prywatny

Uhm, w PHP4 raczej nie ma prywatnych konstruktorów, więc to wszystko jest takie umowne, nie?
rzseattle
Cytat
rzseattle: prawdę mówiąc to ten kod (mnie przynajmniej) w php4 nie działa mimo że wywołuję metodę singleton poprzez
[php:1:a773d9567a]<?php klasa::singleton(); ?>[/php:1:a773d9567a]


8O

Hmm ciekawe. U mnie caly silnik opiera sie wlasnie na takich singletonach i dziala bez zarzutu. Pozatym rozwiazanie FiDO jest identyczne. Jesli u ciebie nie dzialalo to nie mam pojecia dlaczego.
halfik
Cytat
Uhm, w PHP4 raczej nie ma prywatnych konstruktorów, więc to wszystko jest takie umowne, nie?

No fakt. Ale w 5 już są smile.gif Swoją drogą: wczoraj zassałem 5.0.0rc1 - zdążył mi juz 5 razy wysypać apache'a - jest jako moduł tongue.gif
seaquest
hmm haflik nie wiem czy do konca przeczytales temat: Singletony w php4
W sumie w rozwiazaniu FiDO nie podoba mi sie to, ze instancja jest przechowywana w metodzie, ale moze to jedyne rozwiazanie...
No coz, ja w tej chwili mam duzo pracy w dev, ale caly czas bawie sie singletonami, bo chce ich uzywac, ale rownoczesnie chce, zeby moj kod dzialal i w PHP4 i w PHP5
Cudi
Hmm... od 3 tygodni mam gotowy zarys artykułu o Singletonach w 4, i jakos nie moge sie zebrać zeby do XML'a wsadzić... A widze że mogłoby sie przydać. Oczywiście w arcie opisana jest metoda przedstawiona przez FiDO, opisane tez jest dlaczego nie warto stosować zmiennych globalnych, i dlaczego instancje powinna zwracać metoda danej klasy, a nie jakaś funkcja z zewnątrz. Będe musiał postarać sie dokończyć tego arta smile.gif
FiDO
Cytat
A ja myślę, że to nie jest taki całkiem singleton, bo w tym wzorcu konstruktor MUSI być prywatny, bo jak inaczej chesz wymusić na programiście-kliencie używanie jakiejś metody do towrzenia instancji klasy? A tak robisz prywatny konstruktor i klasa sama w sobie tworzy obiekt i zwraca referencję do niego.

Tak jak mowisz, tyle ze w jak napisal juz hawk w php4 nie da sie tak zrobic bo nie ma modyfikatorow dostepu. Ten kod jest wynikiem metamorfozy tego:
Kod
#include <iostream>



using namespace std;



class Singleton {

    static Singleton *instance;



    Singleton() : cos(0)

    {

        cout << "Singleton::Singleton()n";

    }



public:



    int cos;

        

    static Singleton* GetInstance()

    {

        if (Singleton::instance == NULL)

        {

            Singleton::instance = new Singleton;

        }

        return Singleton::instance;

    }

};



Singleton* Singleton::instance = NULL;



int main()

{

    Singleton *a, *b, *c;



    a = Singleton::GetInstance();

    b = Singleton::GetInstance();

    c = Singleton::GetInstance();



    cout << a->cos << ", " << b->cos << ", " << c->cos << endl;

    a->cos++;

    cout << a->cos << ", " << b->cos << ", " << c->cos << endl;

    b->cos++;

    cout << a->cos << ", " << b->cos << ", " << c->cos << endl;



    return 0;

}

Jest to kod, ktory "stworzylem" przed tym w php, zeby sie upewnic, ze da sie zrobic "idealny" singleton (obiekt tworzony tylko i wylacznie za pomoca statycznej metody), kod jest w Cpp i staralem sie maxymalnie go odzwierciedlic, ale jak widac malo z tego co mozna w Cpp da sie w php4, stad ta umowna prywatnosc konstruktora.

Cytat
W sumie w rozwiazaniu FiDO nie podoba mi sie to, ze instancja jest przechowywana w metodzie, ale moze to jedyne rozwiazanie...

Niestety chyba jedyna, tez wolalbym zeby to wygladalo tak jak w przykladzie wyzej, ale w php4 nie ma statycznych pol w klasach, wiec mozna tylko tak.
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.