Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  PHP parent::__construct() singleton märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
Hinnavaatlus :: Foorum :: Uudised :: Ärifoorumid :: HV F1 ennustusvõistlus :: Pangalink :: Telekavad :: HV toote otsing
autor
sõnum Saada viide sõbrale.  :: Teata moderaatorile teata moderaatorile
otsing:  
kullar
HV kasutaja
kullar

liitunud: 26.11.2006



Autoriseeritud ID-kaardiga

sõnum 08.09.2010 22:09:07 PHP parent::__construct() singleton vasta tsitaadiga

Küsimus selline, kas kuidagi on võimalik parent::_construct(); meetodit välja kutsuda ka singleton'ina? Olukord selline kus üks klass extendib teist klassi ja kolmas klass kutsutakse välja esimese klassi sees, mis ekstendib uuesti teist klassi. Selline olukord on tekkinud ajaloolistel põhjustel ja sooviks sellest lahti saada. Parim variant oleks kui saaks parent::_construct meetodi kutsuda välja singletonina. Nt parent::getInstance(); ja $this säiliks.

Näidis hetke olukorrast:

Kutsutakse välja nii:

$_objIndex = A::getInstance();
$_objindex->Parse();

class A extends B
class C extends B
class B extends D


Aga kuna kõik kutsutakse välja läbi classi A, siis tekib olukod, kus class B initsialiseeritakse 2 korda.
Lisaks sooviks et classis C saaks jätkuvalt kasutada $this muutujat nii, nagu senini on olnud.
Nt oletame et classis D on meetod helloWorld, siis classis C saaks kutsuda $this->helloWorld();
Lihtne parent::getInstance() ei toimi, kuna ei saa class D meetoditele ligi.

Loodame, et keegi saab aru ja oskab midagi kosta.

_________________
Online Perekonna Eelarve, Keerukamad veebipõhised infosüsteemid jms
Kommentaarid: 27 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 25
tagasi üles
vaata kasutaja infot saada privaatsõnum
keevitaja
AM 10 aastat
keevitaja

liitunud: 05.11.2001




sõnum 09.09.2010 02:04:41 vasta tsitaadiga

ma ei saa küll aru täpselt mida sa taga ajad, aga alates PHP 5.3 on olemas late static binding, kus saab teha midagi taolist:

php:
  1. <?php
  2. class A {
  3.   static $text;
  4.   static $test = 'see on test';
  5.  
  6.   public static function init() {
  7.     return new static;
  8.   } 
  9.  
  10.   public function print_text() {
  11.     print(static::$text);
  12.   }
  13.  
  14.   public function print_test() {
  15.     print($this->test());
  16.   }
  17. }
  18.  
  19. class B extends A {
  20.   static $text = 'see on tekst';
  21.   static $test;
  22.  
  23.   public function test() {
  24.     return '<br />' . parent::$test;
  25.   }
  26. }
  27.  
  28. $object = B::init();
  29. $object->print_text();
  30. $object->print_test();

_________________
Hinnavaatlus ei ole koht arvamuse avaldamiseks!
Kommentaarid: 51 loe/lisa Kasutajad arvavad:  :: 1 :: 3 :: 40
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
kullar
HV kasutaja
kullar

liitunud: 26.11.2006



Autoriseeritud ID-kaardiga

sõnum 09.09.2010 08:42:22 vasta tsitaadiga

Sa ei saa päris aru. Proovi see jupp käima lasta, siis näed, et class regbase kutsutakse 2korda välja ja soovin teada, kas seda on võimalik vältida,ilma et hakkaks classide extendimisi ja struktuure ümber tegema.
Et nt classis users konstruktoris kutsudavälja parent::getInstance();, mis oleks samal ajal võrdne parent::__construct();meetodiga ning mis ei lase classil regbase 2 korda initsialiseerida.
php:
  1.  
  2. <?php
  3. class users extends regbase{
  4.         public function __construct(){
  5.           parent::__construct();
  6.         }
  7. }
  8.  
  9. class index extends users{
  10.         protected static $instance = NULL;   
  11.  
  12.         public function __construct(){
  13.                 parent::__construct();
  14.         }
  15.  
  16.         public static function getInstance(){
  17.                 if(!self::$instance){
  18.                         self::$instance = new index;
  19.                 }
  20.                 return self::$instance;
  21.         }
  22.        
  23.         public function getSomeClass(){
  24.                 $_objGraph = new graafikud();
  25.                 return $_objGraph->getHelloFromRegbase();
  26.         }
  27. }
  28.  
  29.  
  30. class graafikud extends users{
  31.         public function __construct(){
  32.            parent::__construct();
  33.         }
  34.        
  35.         public function getHelloFromRegbase(){
  36.               return $this->helloWorld();
  37.         }
  38. }
  39.  
  40. class regbase{
  41.         public static $count;
  42.         public function __construct(){
  43.                 regbase::$count++;
  44.                
  45.                 echo regbase::$count.'<br>';
  46.         }
  47.  
  48.         public function helloWorld(){
  49.              return 'helloWorld From regbase';
  50.         }
  51. }
  52.  
  53.  
  54. $_objIndex = index::getInstance();
  55. echo $_objIndex->getSomeClass();
  56. ?>
  57.  

_________________
Online Perekonna Eelarve, Keerukamad veebipõhised infosüsteemid jms
Kommentaarid: 27 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 25
tagasi üles
vaata kasutaja infot saada privaatsõnum
karu
HV kasutaja

liitunud: 08.08.2002




sõnum 09.09.2010 09:01:02 vasta tsitaadiga

singleton constructor peab olema private.

tee nimeta regbase ümber RegbaseSingleton classiks ja tekita regbase class mis kasutab RegbaseSingleton'i
Kommentaarid: 1 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 1
tagasi üles
vaata kasutaja infot saada privaatsõnum
kullar
HV kasutaja
kullar

liitunud: 26.11.2006



Autoriseeritud ID-kaardiga

sõnum 09.09.2010 11:07:30 vasta tsitaadiga

Tänud karu, uurin natuke edasi. regbase kutsutakse tõesti nüüd 1 kord välja, kuid ka users loetakse 2 korda sisse.
Proovin natuke users classi ümber teha ja muuta ta usersSingletoniks. Hetkel jõudsin tulemuseni, kus usersSingleton(vana users) kutsutakse üks kord välja, kuid regbase konstruktorit mitte. Uurin natuke.

_________________
Online Perekonna Eelarve, Keerukamad veebipõhised infosüsteemid jms
Kommentaarid: 27 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 25
tagasi üles
vaata kasutaja infot saada privaatsõnum
karu
HV kasutaja

liitunud: 08.08.2002




sõnum 09.09.2010 13:20:57 vasta tsitaadiga

kullar kirjutas:
Tänud karu, uurin natuke edasi. regbase kutsutakse tõesti nüüd 1 kord välja, kuid ka users loetakse 2 korda sisse.
Proovin natuke users classi ümber teha ja muuta ta usersSingletoniks. Hetkel jõudsin tulemuseni, kus usersSingleton(vana users) kutsutakse üks kord välja, kuid regbase konstruktorit mitte. Uurin natuke.
tundub, et Sul seal üks paras sasipundar.

UserClass / RegbaseClass on proxy classid realsetele singleton klassidele.
vaata ka, et sul ei oleks "class UserSingleton extends RegbaseSingleton"

UserSingleton'i tõsta kõik mis on omased User klassile, ülejäänud jõuavad 'User extends Regbase' radapidi RegbaseSingleton'i. Pea ka meeles, et User/RegbaseClass'i muutujad on kõik Singleton klassides.

--

või viska singleton välja, defineeri user/regbase klassi muutujad 'static' ja classi funktsioonides $this->muutuja asemel kasuta self::$muutuja. construktoris siis pead arvestust kas muutujad on algväärtustatud või mitte.
Kommentaarid: 1 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 1
tagasi üles
vaata kasutaja infot saada privaatsõnum
kullar
HV kasutaja
kullar

liitunud: 26.11.2006



Autoriseeritud ID-kaardiga

sõnum 09.09.2010 14:35:45 vasta tsitaadiga

Ei vaidle üldse vastu, et tegu on päris suure jamaga. Võtsin selle singleton classi üldse välja, pole toda sinna vahele vaja hetkel(Üleliigne load).
Nüüd on täpselt selline olukord, miks ei saa kasutada user::getInstance() ja saab kasutada parent::__construct(); kuna regbase'i $db objekti muutuja ei jõua index objekti ega graafikud objekti.
Kui asendada rida 23 reaga 22 ja rida 46 reaga 45, siis kõik OK, kuid jookustab regbase'i 2 korda.

php:
  1.  
  2. <?php
  3. class users extends regbase {
  4.         protected static $instance = NULL;
  5.        
  6.         public function __construct(){
  7.                 parent::__construct();
  8.         }
  9.        
  10.         public static function getInstance(){
  11.                 if(!self::$instance){
  12.                         self::$instance = new users;
  13.                 }
  14.                 return self::$instance;
  15.         }
  16. }
  17.  
  18. class index extends users{
  19.         protected static $instance = NULL;   
  20.  
  21.         public function __construct(){
  22.                 #parent::__construct();
  23.                 users::getInstance();
  24.         }
  25.  
  26.         public static function getInstance(){
  27.                 if(!self::$instance){
  28.                         self::$instance = new index;
  29.                 }
  30.                 return self::$instance;
  31.         }
  32.        
  33.         public function getSomeClass(){
  34.                 $o = $this->db.' ('.__CLASS__.'->'.__FUNCTION__.'[line:'.__LINE__.'])<br />';
  35.                
  36.                 $_objGraph = new graafikud();
  37.                 $o.= $_objGraph->getHelloFromRegbase();
  38.                
  39.                 return $o;
  40.         }
  41. }
  42.  
  43. class graafikud extends users{
  44.         public function __construct(){
  45.            #parent::__construct();
  46.                 users::getInstance();
  47.         }
  48.        
  49.         public function getHelloFromRegbase(){
  50.               $o = $this->db.' ('.__CLASS__.'->'.__FUNCTION__.'[line:'.__LINE__.'])<br />';
  51.               $o.= $this->helloWorld();
  52.              
  53.               return $o;
  54.         }
  55. }
  56.  
  57. class regbase{
  58.         public static $count;
  59.         public $db = 'db con puudub';
  60.        
  61.         public function __construct(){
  62.                 self::$count++;
  63.                 $this->db = 'db con olemas';
  64.                
  65.                 #echo '<pre>';print_r(debug_backtrace());echo '</pre>';
  66.         }
  67.  
  68.         public function helloWorld(){
  69.              return '<b>'.self::$count.' korda</b> helloWorld From regbase<br />';
  70.         }
  71. }
  72.  
  73. $_objIndex = index::getInstance();
  74. echo $_objIndex->getSomeClass();
  75. ?>
  76.  

_________________
Online Perekonna Eelarve, Keerukamad veebipõhised infosüsteemid jms
Kommentaarid: 27 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 25
tagasi üles
vaata kasutaja infot saada privaatsõnum
karu
HV kasutaja

liitunud: 08.08.2002




sõnum 09.09.2010 15:48:31 vasta tsitaadiga

kullar kirjutas:
Ei vaidle üldse vastu, et tegu on päris suure jamaga. Võtsin selle singleton classi üldse välja, pole toda sinna vahele vaja hetkel(Üleliigne load).
Nüüd on täpselt selline olukord, miks ei saa kasutada user::getInstance() ja saab kasutada parent::__construct(); kuna regbase'i $db objekti muutuja ei jõua index objekti ega graafikud objekti.
Kui asendada rida 23 reaga 22 ja rida 46 reaga 45, siis kõik OK, kuid jookustab regbase'i 2 korda.

Sa ei vaja getInstance().

$db'd üritad ühe korra tekitada (mis on mõistlik) ?

siis tekita see väljaspool klassi ja anna klassi tekitamisel ette, näiteks
$db = new Sql();
$idx = new Index($db)
mis siis edastab selle parent::__constructor($db) kaudu user classi ja see omakorda regbase klassi (sellisel juhul $db ei tohiks olla static).

või võid ka teha nagu all on tehtud, regbase construct() täidetakse ainult üks kord. Sellisel juhul aga peavad kõik muutujad olemas defineeritud 'static' ja juurdepääs toimub siis self::$db kaudu. Index/User/Graafikud kõik kolm klassi ja ükskõik mitu korda sa new Index() teed, kõik jagavad ühte ja sama $db väärtust. Muudad ühes, muutub ka kõigis teistes.

Regbase construct() näitel saad ka user'i teha ühekordseks, aga jällegi peavad kõik muutujad siis static olema

php:
  1.  
  2. <?php
  3. class regbase{
  4.         public static $count=0;
  5.         public static $db = 'db con puudub';
  6.        
  7.         public function __construct(){
  8.                 static $done=false;
  9.                 if($done) return;
  10.                 $done = true;
  11.  
  12.                 self::$count++;
  13.                 self::$db = 'db con olemas';
  14.                 #echo '<pre>';print_r(debug_backtrace());echo '</pre>';
  15.         }
  16.  
  17.         public function helloWorld(){
  18.              return '<b>'.self::$count.' korda</b> helloWorld From regbase<br />';
  19.         }
  20. }
  21.  
  22. class users extends regbase {
  23.        
  24.         public function __construct(){
  25.                 parent::__construct();
  26.         }
  27.        
  28. }
  29.  
  30. class index extends users{
  31.  
  32.         public function __construct(){
  33.                 parent::__construct();
  34.         }
  35.        
  36.         public function getSomeClass(){
  37.                 $o = self::$db.' ('.__CLASS__.'->'.__FUNCTION__.'[line:'.__LINE__.'])<br />';
  38.                
  39.                 $_objGraph = new graafikud();
  40.                 $o.= $_objGraph->getHelloFromRegbase();
  41.                
  42.                 return $o;
  43.         }
  44. }
  45.  
  46. class graafikud extends users{
  47.         public function __construct(){
  48.            parent::__construct();
  49.         }
  50.        
  51.         public function getHelloFromRegbase(){
  52.               $o = self::$db.' ('.__CLASS__.'->'.__FUNCTION__.'[line:'.__LINE__.'])<br />';
  53.               $o.= $this->helloWorld();
  54.              
  55.               return $o;
  56.         }
  57. }
  58.  
  59.  
  60. $_objIndex = new index;
  61. echo $_objIndex->getSomeClass();
  62.  
  63. //eof
  64.  
Kommentaarid: 1 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 1
tagasi üles
vaata kasutaja infot saada privaatsõnum
kullar
HV kasutaja
kullar

liitunud: 26.11.2006



Autoriseeritud ID-kaardiga

sõnum 10.09.2010 08:24:59 vasta tsitaadiga

Karu, mõtlesin ka ise alguses, et annan indexile db objekti kaasa, kuid kuna regbases pole ainult db objekt, vaid ka muid regbase'i muutujaid ja neid pole küll mõtet kaasa anda. Staticutut kahjuks kasutada ei taha. Vaatan ja uurin veel maad, kuna google'ist otsides polnud ma ainuke, kes sellise probleemiga kokku puutunud.
_________________
Online Perekonna Eelarve, Keerukamad veebipõhised infosüsteemid jms
Kommentaarid: 27 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 25
tagasi üles
vaata kasutaja infot saada privaatsõnum
näita postitusi alates eelmisest:   
uus teema   vasta Tarkvara »  Programmeerimine »  PHP parent::__construct() singleton
[vaata eelmist teemat] [vaata järgmist teemat]
 lisa lemmikuks
näita foorumit:  
 ignoreeri teemat 
sa ei või postitada uusi teemasid siia foorumisse
sa ei või vastata selle foorumi teemadele
sa ei või muuta oma postitusi selles foorumis
sa ei või kustutada oma postitusi selles foorumis
sa ei või vastata küsitlustele selles foorumis
sa ei saa lisada manuseid selles foorumis
sa võid manuseid alla laadida selles foorumis



Hinnavaatlus ei vastuta foorumis tehtud postituste eest.