Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> Singleton i dziedziczenie
relaxant
post 3.07.2006, 12:13:44
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 3.07.2006, 12:47:11
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 3.07.2006, 13:05:35
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 tongue.gif
Go to the top of the page
+Quote Post
mariuszn3
post 3.07.2006, 13:08:37
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 3.07.2006, 13:12:18
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


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
relaxant
post 3.07.2006, 13:16:28
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 3.07.2006, 13:25:19
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.


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
bigZbig
post 3.07.2006, 13:35:19
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.


--------------------
bigZbig (Zbigniew Heintze) | blog.heintze.pl
Go to the top of the page
+Quote Post
nospor
post 3.07.2006, 13:38:48
Post #9





Grupa: Moderatorzy
Postów: 36 557
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 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 smile.gif


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
Cysiaczek
post 3.07.2006, 13:40:03
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


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
mariuszn3
post 3.07.2006, 13:56:18
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 3.07.2006, 14:01:22
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


--------------------
bigZbig (Zbigniew Heintze) | blog.heintze.pl
Go to the top of the page
+Quote Post
Cysiaczek
post 3.07.2006, 14:02:01
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


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
mariuszn3
post 3.07.2006, 14:08:05
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 3.07.2006, 14:10:31
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


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
mariuszn3
post 3.07.2006, 14:19:33
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 smile.gif

Ten post edytował mariuszn3 3.07.2006, 14:25:55
Go to the top of the page
+Quote Post
relaxant
post 3.07.2006, 14:26:57
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 3.07.2006, 15:37:43
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 3.07.2006, 15:42:27
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 smile.gif

Ten post edytował Cysiaczek 3.07.2006, 15:43:35


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
NuLL
post 3.07.2006, 17:58:16
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 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


--------------------
Javascript, Coffeescript, Node.js, Mongo, CouchDb, chmury, workery & inne bajery - zycie jest zbyt krotkie aby miec nudna prace :)
Go to the top of the page
+Quote Post

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

 



RSS Wersja Lo-Fi Aktualny czas: 29.06.2025 - 17:48