[PHP] Implementatie 'Singleton' pattern m.b.v. static *

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Tom-Eric
  • Registratie: Oktober 2001
  • Laatst online: 25-03 09:11
Ik gebruik het Singleton pattern bij oa. een database class, maar terwijl ik aan het debuggen was met xdebug viel me op dat er 3 keer mysql_connect werd aangeroepen. Hierna heb ik een test script gemaakt die er als volgt uitziet:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?php
class   Test
{
    var $_microtime;
    
    function    &Test()
    {
        $this->_microtime   =   microtime();
    }
    
    function    &getMicrotime()
    {
        return  $this->_microtime;
    }
    
    function    &getInstance()
    {
        static  $instance;
        
        if(!isset($instance))
        {
            $instance   =&  new Test();
        }
        
        return  $instance;
    }
}

$a  =   Test::getInstance();
$b  =   Test::getInstance();
$c  =   Test::getInstance();

print('$a->_microtime: ' . $a->getMicrotime() . '<br />');
print('$b->_microtime: ' . $b->getMicrotime() . '<br />');
print('$c->_microtime: ' . $c->getMicrotime() . '<br />');
?>

Als ik deze uitvoer, dan krijg ik de volgende output:
code:
1
2
3
$a->_microtime: 0.50899500 1078238283
$b->_microtime: 0.50910000 1078238283
$c->_microtime: 0.50917100 1078238283

Als ik de regel:
PHP:
22
            $instance    =&    new    Test();

wijzig in:
PHP:
22
            $instance    =    new    Test();

dan krijg ik de volgende output:
code:
1
2
3
$a->_microtime: 0.34313800 1078238472
$b->_microtime: 0.34313800 1078238472
$c->_microtime: 0.34313800 1078238472

Mijn vraag is nu, is dit een bug in PHP, of klopt er iets niet in mijn denkwijze? Ik gebruik trouwens PHP-4.3.4 op Windows.

[ Voor 24% gewijzigd door Tom-Eric op 02-03-2004 16:52 ]

i76 | Webdesignersgids | Online Gitaarlessen & Muziekwinkels


Acties:
  • 0 Henk 'm!

  • Sjaaky
  • Registratie: Oktober 2000
  • Laatst online: 20-09 23:02
Je denkwijze klopt niet :). Althans hij komt niet overeen met die van de makers van php. Mijn denkwijze (en nog wel van meer mensen) overigens ook niet. Als je references in php wilt snappen moet een hele rare kronkel in je denkwijze aanbrengen, dat is me nog niet gelukt.
Advies: als je dit soort dingen in php wilt doen kun je beter php5 pakken. Als je het in php4 wilt doen, moet je dit soort dingen niet willen.

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Als je references in php wilt snappen moet een hele rare kronkel in je denkwijze aanbrengen, dat is me nog niet gelukt.
Wat is die kronkel dan precies?

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

(jarig!)
Bij mijn weten hoort bovenstaande code inderdaad gewoon te werken, blijkbaar beschouwt php een reference naar een object in een static-var als leeg ofzo :?

Acties:
  • 0 Henk 'm!

  • raoulduke
  • Registratie: Oktober 2003
  • Niet online

raoulduke

Get in!

Remember, if you have any trouble you can always send a telegram to the Right People.


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Het frappante is dat de constructor kennelijk wel 3x aangeroepen wordt. Het lijkt wel, door de new & instantiatie, dat die hele assignment gewoon niet plaats vindt, maar de constructie wel... Wat voor waarde je die static ook geeft (in eerste instantie), die blijft behouden in die static:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Test
{
    function Test () { echo "constructie;"; }
    function    &getInstance() {
        static    $instance = 'piet';
        if($instance=='piet') {
            var_dump ( $instance );
            $instance = &new Test();
        }
        return    $instance;
    }
}

$a    =    Test::getInstance();
$b    =    Test::getInstance();
$c    =    Test::getInstance();

Uitvoer:
string(4) "piet"
constructie;string(4) "piet"
constructie;string(4) "piet"
constructie;
Valt wel redelijk in de categorie 'rare bug', imo :)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • Tom-Eric
  • Registratie: Oktober 2001
  • Laatst online: 25-03 09:11
Ik dacht eventueel een workaround gevonden te hebben door het volgende te gebruiken:
PHP:
22
23
$object   =&    new Test();
$instance =&    $object;

Dit had echter hetzelfde (ongewenste) resultaat, maar toen ik de code veranderde naar:
PHP:
22
23
$object   = new Test();
$instance =&    $object;

kreeg ik tegen mijn verwachting in weer het ongewenste resultaat. Na een beetje testen kom ik tot de conclusie dat static variabelen en references niet samen gaan.

[ Voor 7% gewijzigd door Tom-Eric op 02-03-2004 19:34 ]

i76 | Webdesignersgids | Online Gitaarlessen & Muziekwinkels

Pagina: 1