[php] class overerving en static function calls.

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Uhmmie
  • Registratie: Januari 2000
  • Laatst online: 20-08 17:30
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
class myParent
{
    protected final function __construct(){}
    
    public static function getInstance() {
        static $instances;
        $classname = get_class();
        if (!isset($instances[$classname])) {
            $instances[$classname] = new $classname();
        }
        return $instances[$classname];
    }   
}

class myChild extends myParent
{
    ........
}

print_r(myChild::getInstance());
?>

Output:myParent Object ( )

Probleem is dat ik nu als nog een myParent object terug krijg ipv een myChild, omdat get_class de class terug geeft van de class waarin het aangeroepen wordt en geen rekening houdt met de over erving. Nu vroeg ik me af of er echt geen mogelijkheid is om een myChild object terug te krijgen zonder dat ik in myChild de getInstance functie moet overschrijven? Want dat haalt de hele OOP gedachte gang onderuit.

[ Voor 4% gewijzigd door Uhmmie op 23-04-2008 21:32 . Reden: output toegevoegd. ]

Currently playing: MTG Arena (PC)


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 20:01
Waarom haalt dat de hele OO gedachtengang onderuit ? Een static method is niet gebonden aan een instance.

(Trouwens, overerven van een singleton vind ik geen goed idee. Een singleton zorgt ervoor dat je hooguit één instance van een bepaalde class kunt hebben.
Als je overerft van een singleton -zoals jij nu doet- kan je dan een myChild instance hebben als je al een myParent instance hebt ? Een myChild is nl een myParent.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Morax
  • Registratie: Mei 2002
  • Laatst online: 20:32
Dit is een iets ander case, laat maar.... :X

[ Voor 81% gewijzigd door Morax op 23-04-2008 21:07 ]

What do you mean I have no life? I am a gamer, I got millions!


Acties:
  • 0 Henk 'm!

  • Uhmmie
  • Registratie: Januari 2000
  • Laatst online: 20-08 17:30
Het is niet de bedoeling dat ik een myParent object aanmaak, maar dat ik in myParent een aantal functies defineer die alle classes moeten hebben. En van iedere child class wil ik inderdaad maximaal maar 1 instance hebben (vandaar het singleton princiepe).

Als ik de getInstance() overschrijf op de volgende manier, werkt het wel:
code:
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
<?php

class myParent
{
    protected final function __construct(){}
    
    protected static function getInstance($classname) {
        static $instances;
        if (!isset($instances[$classname])) {
            $instances[$classname] = new $classname();
        }
        return $instances[$classname];
    }   
}

class myChildA extends myParent
{
    public static function getInstance() {
        return parent::getInstance(get_class());
    }
}

class myChildB extends myParent
{
    public static function getInstance() {
        return parent::getInstance(get_class());
    }
}

print_r(myChildA::getInstance());
print_r(MyChildB::getInstance());

?>

Output:myChildA Object ( ) myChildB Object ( )

Alleen dat betekend dus dat ik dan alsnog de getInstance() functie in al mijn classes moet gaan defineren. Is er echt geen mogelijkheid waarbij ik de gehele getInstance functie in mijn myParent class kan houden?

Currently playing: MTG Arena (PC)


Acties:
  • 0 Henk 'm!

  • user109731
  • Registratie: Maart 2004
  • Niet online
Ik heb hier pas ook naar gezocht, maar volgens mij kan het (nog) niet anders. In non-static methods kun je get_class($this) gebruiken, maar hier gaat dat dus niet. Ook get_class(self) werkt niet.

Hier heb je Late Static Binding voor nodig, wat mogelijk in PHP 5.3 komt. Dan kun je get_called_class gebruiken, zoals hier. Het zit er dus wel aan te komen :)

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Php is op dit gebied inderdaad nogal raar. Het probleem ligt bij de static. Het gaat namelijk zowel mis bij static variabelen als static functions. Beide worden bij overerving niet zoals verwacht meegenomen. Je krijgt namelijk bij de child de geretourneerde waarde van de parent terug, en niet de child. Bij niet-static variabelen en functies is dit dus precies andersom.

Acties:
  • 0 Henk 'm!

  • daniëlpunt
  • Registratie: Maart 2004
  • Niet online

daniëlpunt

monkey's gone to heaven

Iemand vroeg mij laatst om het zelfde. Ik kwam er ook niet echt uit, alleen door de child classes een method te laten over erven die de class naam doorgeeft.

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?php

/**
 * Base class for Singletons
 */
abstract class AbstractSingleton
{
    /**
     * @var Array Holds all instances of the child classes
     */
    protected static $Instances = array();
    /**
     * No direct instances of the child classes
     */
    abstract protected function __construct();
    /**
     * And also no cloneing!
     */
    public final function __clone()
    {
        throw new Exception('Cannot clone Singleton instances');
    }
    /**
     * @param string $Classname
     * @return object Singleton
     */
    protected final static function GetInstance($Classname)
    {
        if (self::$Instances[$Classname] instanceof $Classname == false)
            self::$Instances[$Classname] = new $Classname;

        return self::$Instances[$Classname];
    }
    /**
     * The singleton method, should be the same in every child class
     */
    abstract public static function Singleton();
    /**
     * The method every child class should implement, commented out
     */
    // public static function Singleton()
    // {
    //  return parent::GetInstance(__CLASS__);
    // }
}

/**
 * Implementation of the AbstractSingleton : The world famous FooBar!
 */
class FooBar extends AbstractSingleton
{
    /**
     * Every class needs a constructor
     */
    protected function __construct()
    {
        echo "I am the only one!\n";
    }
    /**
     * The singleton method
     * @return FooBar Object
     */
    public static function Singleton()
    {
        return parent::GetInstance(__CLASS__);
    }
}


FooBar::Singleton();
FooBar::Singleton();
// Output : I am the only one!

Acties:
  • 0 Henk 'm!

  • Uhmmie
  • Registratie: Januari 2000
  • Laatst online: 20-08 17:30
Bedankt voor de reacties.. Dan blijf ik maar even de bovenstaande manier gebruiken tot er een nieuwe versie van php beschikbaar is.

Daarnaast liep ik net nog tegen een ander klein probleem aan: Warning: Call-time pass-by-reference has been deprecated; If you would like to pass it by reference, modify the declaration of [runtime function name](). If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file

Nou kan ik dus wel even mijn ini file aanpassen, maar eigenlijk willen ze dus niet meer dat ik:
code:
1
$class->$func(&$object)
uitvoer? hoe zou ik dit dan moeten aanroepen?

edit: ik heb al door wat ik verkeerd doe volgens php5 ;)

[ Voor 4% gewijzigd door Uhmmie op 24-04-2008 00:20 ]

Currently playing: MTG Arena (PC)


Acties:
  • 0 Henk 'm!

  • remcotolsma
  • Registratie: December 2005
  • Laatst online: 08-09 11:11
Late Static Bindings
http://www.php.net/manual....late-static-bindings.php

Is vanaf PHP 5.3 geïntroduceerd, is dat niet de oplossing voor je probleem?

Acties:
  • 0 Henk 'm!

  • Uhmmie
  • Registratie: Januari 2000
  • Laatst online: 20-08 17:30
yup dat is dus precies wat ik nodig heb :).. Nog even wachten dus tot 5.3 uit is :).

[ Voor 31% gewijzigd door Uhmmie op 24-04-2008 00:23 ]

Currently playing: MTG Arena (PC)


Acties:
  • 0 Henk 'm!

Verwijderd

ik weet niet zeker of dit is wat je wil. dit is puur bedoelt om methods in het child object vanuit de parent aan te roepen. jouw singleton voorbeeld werkt nog steeds niet.

Acties:
  • 0 Henk 'm!

  • Uhmmie
  • Registratie: Januari 2000
  • Laatst online: 20-08 17:30
Ik heb net zitten testen (had er gisteren avond geen zin meer in) en het lijkt idd toch wat anders te zijn.. Is het nu echt zo raar dat ik mijn getInstance alleen in de parent class wil defineren? (zoals in mijn 1ste voorbeeld) ipv ook een entry te moeten maken in iedere subclass (zoals voorbeeld 2).

Currently playing: MTG Arena (PC)


Acties:
  • 0 Henk 'm!

  • user109731
  • Registratie: Maart 2004
  • Niet online
Waarom leest niemand mijn post :?
PHP:
1
$classname = get_called_class();

Werkt prima in PHP 5.3 :)

[ Voor 5% gewijzigd door user109731 op 24-04-2008 10:41 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

mithras schreef op woensdag 23 april 2008 @ 22:35:
Php is op dit gebied inderdaad nogal raar. Het probleem ligt bij de static. Het gaat namelijk zowel mis bij static variabelen als static functions. Beide worden bij overerving niet zoals verwacht meegenomen.
Dat is helemaal niet raar, dat is precies zoals je het zou verwacht.

Een static methode is een methode die je aanroept op de class zelf, dus niet op de instantie. Er is dus ook helemaal niks te overerven aan.

Nooit verwacht dat ik zou ageren tegen een opmerking dat php raar zou zijn ;)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Uhmmie
  • Registratie: Januari 2000
  • Laatst online: 20-08 17:30
JanDM schreef op donderdag 24 april 2008 @ 10:35:
Waarom leest niemand mijn post :?
PHP:
1
$classname = get_called_class();

Werkt prima in PHP 5.3 :)
Sorry ik had wel het binding verhaaltje gelezen, maar helemaal de functie over het hoofd gezien 8)7.. Thnx _/-\o_.. Ik ga er meteen ff mee aan de gang.

Currently playing: MTG Arena (PC)

Pagina: 1