[PHP4]Variabele van parent object

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Ik zit met een child class waarvan eerst de parent wordt aangemaakt, waarna een functie in de parent de child aanmaakt. Nu heb ik in de child een variabele nodig:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class parent{
  var $foo;
  function parent(){
    $this->foo = "bar";
  }
  
  function display(){
    $this->child = new child();
    $this->child->display();
  }
}

class child{
  function child(){
    do_something();
  }

  function display(){
    echo parent::foo;    //Hier zoek ik de variabele $parent->foo op
  }
}

$parent = new parent();
Ik krijg een error:
code:
1
Cannot access parent:: when current class scope has no parent in
Dat is waarschijnlijk logisch, omdat ik de class niet extend. Als ik de child class extend met "extends parent" krijg de volgende error:
code:
1
Undefined class constant 'max_width'
Dus toen dacht ik: constante :? Het zal waarschijnlijk wel parent::$foo zijn. Nee, want voila:
code:
1
Access to undeclared static property: statistics::$max_width
Ik weet het nu niet precies meer.

Het probleem zit hem volgens mij in dat ik eerst de parent aanmaak, en niet de child creëer die zijn eigen parent aanmaakt. Ik kan natuurlijk ook de variabele gebruiken via een global $parent met $parent->foo maar dat wil ik eigenlijk niet. Daarnaast hoop ik dat het nog gaat werken onder php4, want ook daar kennen ze wel het parent keyword. Alleen als het _echt_ niet mogelijk is kan php5 wel, maar liever houd ik het bij een php4 compatible systeem :)

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09:39

Janoz

Moderator Devschuur®

!litemod

Je haalt hier 2 dingen door elkaar. Ik heb het idee dat je overerving probeert te gebruiken, terwijl je eigenlijk een soort boom structuur wilt maken. Wat je goed moet beseffen is dat je bij overerving niet over verschillende objecten praat, maar over het steeds verder specialiseren van 1 specifiek object.

Wat jij hier aan het doen bent is in je parent object een 2e class maken die je child noemt. Daar is helemaal niks mis mee, maar heeft niks met overerving te maken. Wil je dat in je child bekend is wat de parrent is dan moet je de child een constructor geven zodat je de parent door kunt geven of een setter gebruiken.

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!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 08:18
De foutmeldingen die je krijgt komen sowieso van PHP5, PHP4 kent afaik klasseconstanten noch static properties. Verder denk ik dat je probleem ligt in een verkeerd begrip van inheritance. Het parent keyword wijst naar een klasse waar de huidige op extend, niet een object. Je kunt het toepassen om expliciet een constante of methode aan te roepen uit de parent.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class parentClass {
    
    public function whoami() {
        echo 'parent' ."\n\n";
    }
}

class childClass extends parentClass {
    public function whoami() {
        echo 'child' ."\n\n";
    }

    public function whosMyDaddy() {
        echo parent::whoami() ."\n\n";
    }
}

$p = new parentClass();
$p->whoami(); //parent

$c = new childClass();
$c->whoami(); //child
$c->whosMyDaddy(); //parent

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Janoz schreef op woensdag 21 februari 2007 @ 09:55:
Je haalt hier 2 dingen door elkaar. Ik heb het idee dat je overerving probeert te gebruiken, terwijl je eigenlijk een soort boom structuur wilt maken. Wat je goed moet beseffen is dat je bij overerving niet over verschillende objecten praat, maar over het steeds verder specialiseren van 1 specifiek object.
Ok, dat snap ik. Wat ik eigenlijk wil bereiken is dat een variabele toegankelijk is voor verschillende childs.

Het parent object handelt statistieken af, en verschillende childs doen de queries en berekeningen e.d. voor specifiek stats per dag, per uur, per browser, per pagina etc. Allemaal hebben ze eenzelfde variabele nodig, dus ik dacht: die zet ik in de parent en dan haal ik die "gewoon" op.
Wat jij hier aan het doen bent is in je parent object een 2e class maken die je child noemt. Daar is helemaal niks mis mee, maar heeft niks met overerving te maken. Wil je dat in je child bekend is wat de parrent is dan moet je de child een constructor geven zodat je de parent door kunt geven of een setter gebruiken.
Ik zit nu in de child met dit
PHP:
1
2
3
4
5
6
7
8
9
10
class child{
  var $parent;
  function child(){
    $this->parent = get_parent_class($this);
  }
  
  function display(){
    echo $this->parent->foo;
  }
}
Zo kan ik dus als het goed is wel de toegang hebben tot foo?
T-MOB schreef op woensdag 21 februari 2007 @ 10:03:
De foutmeldingen die je krijgt komen sowieso van PHP5, PHP4 kent afaik klasseconstanten noch static properties.
Jups, thuis draai ik php5, maar ik wil het graag php4 compatible houden. Foutmeldingen zijn dus wel in php5, dat klopt.
Verder denk ik dat je probleem ligt in een verkeerd begrip van inheritance. Het parent keyword wijst naar een klasse waar de huidige op extend, niet een object. Je kunt het toepassen om expliciet een constante of methode aan te roepen uit de parent.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class parentClass {
    
    public function whoami() {
        echo 'parent' ."\n\n";
    }
}

class childClass extends parentClass {
    public function whoami() {
        echo 'child' ."\n\n";
    }

    public function whosMyDaddy() {
        echo parent::whoami() ."\n\n";
    }
}

$p = new parentClass();
$p->whoami(); //parent

$c = new childClass();
$c->whoami(); //child
$c->whosMyDaddy(); //parent
Ik snap hoe het zit met functies. Daar staan namelijk wél voorbeelden van in de manual. Kennelijk is het wat lastiger met variabelen. Ik zit wat te rommelen in mn code, maar volgens mij kan dit dus ook (of zit ik nu verkeerd te denken?):
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class parentClass {
    
    function parentClass() {
        $this->variable = "apple";
        $this->child = new childClass();
    }
}

class childClass extends parentClass {
    function get_parent_apple() {
        echo parent::variable;
    }
}

$p = new parentClass();
$p->child->get_parent_apple(); //apple

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09:39

Janoz

Moderator Devschuur®

!litemod

Nogmaals, wat T-Mob aangeeft is echte inheritance. Wat jij doet heeft daar helemaal niks mee te maken. Parent en child slaan dus helemaal nergens op. Als je echt inheritance zou gebruiken is de parent class en de child class hetzelfde. Vanuit je child kun je alles van je parent ook aanroepen. Bij echte inheritance weet je parent trouwens helemaal niks van je child.

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!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 08:18
Nee, je kunt geen variabele in een parent hebben omdat een een parent class altijd een klassedefinitie is, terwijl een variabele/property altijd bij een object hoort.

Om data te delen tussen verschillende objecten kun je bijvoorbeeld gebruik maken van een Singleton of een Registry.
Een simpel voorbeeldje:
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
class Registry {

    private $_data;

    private static $_self;

    //singleton registry, cannot create instance but through getInstance()
    private function __construct() {}


    //get singleton instance
    public static function &getInstance() {
        if (empty(self::$_self)) {
            self::$_self = new self();
        }
        return self::$_self;
    }


    //store an object reference
    public function set($label, &$obj) {
        $this->_data[$label] = &$obj;
    }


    //retrieve an object reference
    public function &get ($label) {
        if (isset($this->_data[$label])) {
            $out = &$this->_data[$label];
        } else {
            $out = FALSE;
        }
        return $out;
    }
}

class StatsData {
    //holds data that needs to be accessible globally
}


class StatsDataUser {

    private $_statsData;

    function __construct() {
        $registry = Registry::getInstance();

        //use the registry to get the StatsData Object. Creates a new StatsData
        //object when teh registry doesn't provide one
        if (!$this->_statsData = $registry->get('StatsData')) {
            $this->_statsData = new StatsData();
            $registry->set('StatsData', $this->_statsData);
        }
    }
}

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Je maakt een aantal denkfouten die ook al door Janoz zijn aangestipt. Bepaal eerst wat je wil:
1) een boomstructuur met parents en childs
2) een overerving waarbij child een parent specialiseert.

In het eerste geval doe je het al bijna goed met je huidige code. Laat het overerven weg en maak de constructor van child zodanig dat je daar het parent object aan meegeeft.

In het tweede geval is het essentieel dat je beseft dat een child een parent IS. En dus niet heeft. Ik vermoed dan ook, gezien de naamgeving dat het jou om geval 1 gaat.

(zie ook de mensen voor mij)

Acties:
  • 0 Henk 'm!

  • .Johnny
  • Registratie: September 2002
  • Laatst online: 04-07 11:10
inderdaad, je lijkt wat in de war met parent-child relaties zoals die in XML bestaan.

Als ik je goed begrijp zoek je eerder zoiets:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class mainClass {
  var $sClass1;
  var $sClass2;
  function mainClass() {
    $this->sClass1 = new sClass1($this);
    $this->sClass2 = new sClass2($this);
  }
}

class sClass1 {
  var $mainClass;
  function sClass1($object) {
    $this->mainClass=$object;
  }
}

class sClass2 {
  var $mainClass;
  function sClass2($object) {
    $this->mainClass=$object;
  }
}
$myMainClass=new mainClass();

Je definieert en initieert in de constructor van mainClass de classes sClass1 en sClass2.
Dan kun je uit sClass1 en sClass2 functies en variabelen aanroepen uit mainClass door $this->mainClass, en ook functies aanroepen uit bijvoorbeeld sClass1 van sClass2: $this->mainClass->sClass2

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
_/-\o_ Jeetje wat zijn jullie snel :p

Ik snap nu dat ik een denkfout heb gemaakt, en ik inderdaad _geen_ inheritance wil, maar een boomstructuur (en ik niets met overerving te maken heb). Ik ben er dus uit, bedankt.

Er zijn begrijp ik dus 2 methoden om de parent vast te stellen: door in je constructor het object mee te "vragen" (zoals .Johnny doet) of die stel je vast met get_parent_class (zoals ik hier deed).

[ Voor 3% gewijzigd door mithras op 21-02-2007 13:10 ]

Pagina: 1