Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> Singleton i dziedziczenie
relaxant
post
Post #1





Grupa: Zarejestrowani
Postów: 24
Pomógł: 0
Dołączył: 9.08.2004
Skąd: Bielsko-Biała

Ostrzeżenie: (0%)
-----


Witam,
Wiekszość ludzi piszacych tutaj rozumie chyba jak działa Singleton. Do dzis myslalem ze tez to rozumiem. Czy moze mi ktos wytlumaczyc dlaczego ten kod nizej działa?

Mam kod index.php
  1. <?php
  2. require_once('lib/core/DB.class.php');
  3. $kk = new DB();
  4. $kk->AA();
  5. ?>


DB.class.php:
  1. <?php
  2. class DB extends mysqli{
  3. private static $instance;
  4.  
  5. private function __construct($hostname=DB_HOST, $username=DB_USER, $password=DB_PASSWORD, $database=DB_DATABASE){
  6. $hostname = ($hostname=="")?DB_HOST:$hostname;
  7. $username = ($username=="")?DB_USER:$username;
  8. $password = ($password=="")?DB_PASSWORD:$password;
  9. $database = ($database=="")?DB_DATABASE:$database;
  10.  
  11. //parent::__construct($hostname, $username, $password, $database);
  12. }
  13.  
  14. public static function getInstance() {
  15. if (!isset(self::$instance)) {
  16. self::$instance = new DB();
  17. } 
  18. return self::$instance;
  19. }
  20.  
  21. public function __clone() {
  22. trigger_error('Clone is not allowed.', E_USER_ERROR);
  23. }
  24.  
  25. public function __destruct() {
  26. print "DESTRUCT DB <br>";
  27. }
  28.  
  29. public function AA() {
  30. print "text";
  31. }
  32. }
  33. ?>


I to działa!! Pomimo tego ze konstuktor DB jest prywatny!! Jezeli nie dziedzicze po mysqli wyskakuje blad (reakcja prawidlowa).

testuje na php Version 5.1.2-1
Go to the top of the page
+Quote Post
mariuszn3
post
Post #2





Grupa: Zarejestrowani
Postów: 352
Pomógł: 0
Dołączył: 22.01.2006

Ostrzeżenie: (0%)
-----


Pierwsza sprawa, to pewnie nie dopatrzenie php. Powinien Ci wyskakiwać błąd - klasa DB dziedziczy klasę, w której konstruktor jest publiczny.. tak więc i klasa DB musi mieć publiczny konstruktor. Czyli z założenia masz zły kod.
No ale błędu nie ma i dlaczego w takim razie tak to działa(?) Podejrzewam, że php odwołuje się do konstruktora, który jest widoczny w danym miejscu, czyli jeśli klasa DB ma prywatny, jest on niedostępny z zewnątrz.. natomiast widoczny jest publiczny konstruktor mysqli więc jest on wywoływany.
Bez wnikania w algorytm kodu źródłowego php, trudno mieć pewność czemu to tak się zachowuje.
Go to the top of the page
+Quote Post
relaxant
post
Post #3





Grupa: Zarejestrowani
Postów: 24
Pomógł: 0
Dołączył: 9.08.2004
Skąd: Bielsko-Biała

Ostrzeżenie: (0%)
-----


Tez tak myslalem ze pewnie jest wykonywany publiczny konstruktor mysqli ale wtedy zdaje sie nie powinienem miec dostepu do metody AA, a mam (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)
Go to the top of the page
+Quote Post
mariuszn3
post
Post #4





Grupa: Zarejestrowani
Postów: 352
Pomógł: 0
Dołączył: 22.01.2006

Ostrzeżenie: (0%)
-----


A dlaczego miałbyś nie mieć dostępu do AA? To, że jest wywoływany konstruktor mysqli, nie zmienia faktu, że obiekt jest instancją klasy DB.
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #5





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Jeśli posiadasz wersję php 5.1.x, to chocbyś nie wiem jak kombinował, to konstruktor zawsze jest publiczny. Nie może by prywatny, ani chroniony. Jest o tym wzmianka w changes dla php i chyba nawet w nowym manualu.

Ten post edytował Cysiaczek 3.07.2006, 13:12:55
Go to the top of the page
+Quote Post
relaxant
post
Post #6





Grupa: Zarejestrowani
Postów: 24
Pomógł: 0
Dołączył: 9.08.2004
Skąd: Bielsko-Biała

Ostrzeżenie: (0%)
-----


to chcesz powiedzić, że te wszystkie implementacje singletona w php są nie dokońca ok bo można i tak je obejeść wywołując new ? Private działa, no chyba ze dodatkowo dziedziczymy wtedy się coś chrzani (patrz wyżej)
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #7





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Ideą singletona jest to, że w zakresie całej aplikacji możesz miec tylko jedną instancję klasy. Oczywiście zawsze można to obejś, ale pytanie po co? Singleton to rozwiązanie, które zastępuje nam zmienne globalne (przynajmniej w większości przypadków). Tzw bezpieczeństwo Singletona nie może by rozumiane w takim sensie jak bezpieczeństwo danych etc. To raczej bezpieczeństwo dla programisty, który ma miec pewnośc, że obiekt, który posiada jest obiektem unikalnym i jedynym w całej aplikacji (w konkretnym procesie). Dlatego nie wywołujemy poprzez klucz 'new', tylko specjalną metodę getInstance(), która sprawdza, czy istnieje już jakiś obiekt danej klasy i jeśli nie, to próbuje go wywołac.
Go to the top of the page
+Quote Post
bigZbig
post
Post #8





Grupa: Zarejestrowani
Postów: 740
Pomógł: 15
Dołączył: 23.08.2004
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Ale skoro konstruktor zawsze jest publiczny to o kant stołu dyrektywy public, protected i private. Równie dobrze moglibysmy pozostać jedynie przy oznaczaniu metod prywatnych za pomoca pojedynczego podkreslenia. W koncu chodzi tak naprawde jedynie o poinformowanie programisty o tym z czym ma do czynienia, a co on juz z tym zrobi to już jego sprawa. Szczerze mowiąc w jezykach skryptowych wyzej wspomniane oznaczenia zawsze maja tylko charakter informacyjny bo deklaracje zawsze mozna zmienic, chyba ze mamy do czynienia ze zdalnie wykonywanym kodem, ale to juz inna bajka.
Go to the top of the page
+Quote Post
nospor
post
Post #9





Grupa: Moderatorzy
Postów: 36 559
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
Ale skoro konstruktor zawsze jest publiczny to o kant stołu dyrektywy public, protected i private.
i dlatego przy konstruktorze tej dyrektywy sie nie stosuje (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

zastosuj przy innych funkcjach, a przekonasz sie ze dziala. Swoją drogą mi sie loginczne wydaje, ze konstruktor musi byc publiczny. W koncu pelni on pewna role w klasie (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #10





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Spokojnie. Nie jest tak źle. Wszystkie inne składowe i metody mozna sobie dowolnie ustawic. Całe zamieszanie jest tylko z konstruktorem. Nie jestem w tej dziedzinie ekspertem, ale wydaje mi się, że to może miec związek ze standardami programowania.

i jeszcze...
nospor ma rację. W końcu konstruktor ma za zadanie dokonac operacji, które sa wykonywane dla kazdej instancji klasy.

Ten post edytował Cysiaczek 3.07.2006, 13:42:12
Go to the top of the page
+Quote Post
mariuszn3
post
Post #11





Grupa: Zarejestrowani
Postów: 352
Pomógł: 0
Dołączył: 22.01.2006

Ostrzeżenie: (0%)
-----


Cytat(Cysiaczek @ 3.07.2006, 12:12 ) *
Jeśli posiadasz wersję php 5.1.x, to chocbyś nie wiem jak kombinował, to konstruktor zawsze jest publiczny. Nie może by prywatny, ani chroniony. Jest o tym wzmianka w changes dla php i chyba nawet w nowym manualu.

Skąd te informacje?!? Konstruktor jak najbardziej może być prywatny i nawet należy go tak deklarować w przypadku singletona. Każde odwołanie się z zewnątrz do takiej klasy poprzez 'new' wyrzuci fatal error. Korzystam z 5.1.x i wszystko działa tak jak powyżej.
Go to the top of the page
+Quote Post
bigZbig
post
Post #12





Grupa: Zarejestrowani
Postów: 740
Pomógł: 15
Dołączył: 23.08.2004
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Oj chlopaki - wiem, ze dla pozostalych metod i wlasciwosci to dziala, problem jest innej natury. Brak jest konsekwencji. Albo mozemy konstruktorowi okreslac dostepnosc i wtedy powinny dzialac dyrektywy protected i private albo nie mozemy i wtedy zdefiniowanie takiej deklaracji powinno skutkowac bledem. A jesli ma to byc jedynie oznaczenie umowne to ja jestem za tym zeby to bylo umowne dla wszystkich metod i wlasciwosci.

-- edit --
@mariuszn3 - no i tak powinno byc

Ten post edytował bigZbig 3.07.2006, 14:03:15
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #13





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Zaraz poszukam i wskażę źródło... loading
Go to the top of the page
+Quote Post
mariuszn3
post
Post #14





Grupa: Zarejestrowani
Postów: 352
Pomógł: 0
Dołączył: 22.01.2006

Ostrzeżenie: (0%)
-----


Cytat(Cysiaczek @ 3.07.2006, 13:02 ) *
Zaraz poszukam i wskażę źródło... loading

Po co źródło (chyba, że to jakaś nadchodząca nowinka.. której w ogóle bym się nie spodziewał i na razie nie jestem w stanie zrozumieć).

Przykład na 5.1.3RC4-dev na windzie:
  1. <?php
  2. class test {
  3. private function __construct() {
  4. var_dump(__CLASS__);
  5. }
  6. }
  7. new test;
  8. ?>


Odpowiedź:
  1. Fatal error: Call to private test::__construct() from context ''


Ten post edytował mariuszn3 3.07.2006, 14:08:28
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #15





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




http://pl.php.net/distributions/manual/php...z#language.oop5

Sekcja Method Visibility (patrzcie komentarze w kodzie)

Ja mam php 5.1.4 na Linuksie. Źródło, które podaję, to nieco inne niż to, z którego czerpałem informację. Jestem niemal pewien, że to był changelog lub inny plik w mojej dystrybucji php

Ten post edytował Cysiaczek 3.07.2006, 14:17:26
Go to the top of the page
+Quote Post
mariuszn3
post
Post #16





Grupa: Zarejestrowani
Postów: 352
Pomógł: 0
Dołączył: 22.01.2006

Ostrzeżenie: (0%)
-----


Cytat(Cysiaczek @ 3.07.2006, 13:10 ) *
http://pl.php.net/distributions/manual/php...z#language.oop5

Sekcja Method Visibility (patrzcie komentarze w kodzie)

Myślę, że mocno znadinterpretowałeś ten komentarz.. a swoją drogą nie jest on za bardzo przemyślany jak na komentarz w podręcznikowym przykładzie
Myślę, że autorowi chodziło po prostu o to, że konstruktor musi być publiczny by można było utworzyć obiekt klasy.. ale z zewnątrz.. tak jak tam dalej jest w tym przykładzie.
Zresztą to przykład dla początkujących, którzy dopiero dowiadują się czym jest dostępność i do singleton'ów czy innych wzorców jest tam daleko.. stąd pewnie to nadużycie.

EDIT: W tym samym dziale zobacz sekcję Patterns i Singleton (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Ten post edytował mariuszn3 3.07.2006, 14:25:55
Go to the top of the page
+Quote Post
relaxant
post
Post #17





Grupa: Zarejestrowani
Postów: 24
Pomógł: 0
Dołączył: 9.08.2004
Skąd: Bielsko-Biała

Ostrzeżenie: (0%)
-----


No i spoko " // Contructors must be public" zeby przyklad zadziałał. Ja tu pisze o czymś troche innym patrz ten sam dokument sekcja Patterns (Przykład 19-25. Singleton Function) czyli singletonach w klasach ktore dziedzicza po innych klasach. Zgadzam sie z mariuszn3. Jest to poprostu błąd php'a!
Go to the top of the page
+Quote Post
ActivePlayer
post
Post #18





Grupa: Przyjaciele php.pl
Postów: 1 224
Pomógł: 40
Dołączył: 6.07.2004
Skąd: Wuppertal

Ostrzeżenie: (0%)
-----


jako ze nie mam dostępu do php5 tutaj, zadam pytanie:

  1. <?php
  2. class DB extends mysqli{
  3. private static $instance;
  4.  
  5. private function __construct($hostname=DB_HOST, $username=DB_USER, $password=DB_PASSWORD, $database=DB_DATABASE){
  6. $hostname = ($hostname=="")?DB_HOST:$hostname;
  7. $username = ($username=="")?DB_USER:$username;
  8. $password = ($password=="")?DB_PASSWORD:$password;
  9. $database = ($database=="")?DB_DATABASE:$database;
  10. $this->AA();
  11. //parent::__construct($hostname, $username, $password, $database);
  12. }
  13.  
  14. public static function getInstance() {
  15. if (!isset(self::$instance)) {
  16. self::$instance = new DB();
  17. } 
  18. return self::$instance;
  19. }
  20.  
  21. public function __clone() {
  22. trigger_error('Clone is not allowed.', E_USER_ERROR);
  23. }
  24.  
  25. public function __destruct() {
  26. print "DESTRUCT DB <br>";
  27. }
  28.  
  29. public function AA() {
  30. print "text";
  31. }
  32. }
  33. ?>

  1. <?php
  2. require_once('lib/core/DB.class.php');
  3. $kk = new DB();
  4. ?>

Jaki jest rezultat?
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #19





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Nie chcę się o to kłócic. Jak tylko postawię net na linuksie, to jeszcze raz wszystko sprawdzę i przejrzę moje pliki dystrybucji. Faktycznie niegdy do tej pory nie robiłem prywatnego konstruktora, bo nie widzę w tym większego sensu (używam często zewnętrznych wywołań). Ten kod w manualu widziałem też wcześniej, ale nadal nie moge oprzec się wrażeniu, że czytałem to w jeszcze innym miejscu i to nie w formie komantarza, tylko ładnego okrągłego zdania. Jeśłi się mylę, to oczywiście przepraszam za zamieszanie. Śledztwo w toku (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Ten post edytował Cysiaczek 3.07.2006, 15:43:35
Go to the top of the page
+Quote Post
NuLL
post
Post #20





Grupa: Zarejestrowani
Postów: 2 262
Pomógł: 21
Dołączył: 3.05.2004
Skąd: Sopot, Krakow, W-wa

Ostrzeżenie: (0%)
-----


Cytat
Jeśłi się mylę, to oczywiście przepraszam za zamieszanie

Mylisz sie (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

@AP - rezultatem powinno byc
Cytat
Fatal error: Call to private DB::__construct() from context ''


Ten post edytował NuLL 3.07.2006, 17:58:49
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 26.09.2025 - 15:32