[PHP] __get van parent

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Slagroom
  • Registratie: Juni 2001
  • Laatst online: 05-10-2024
Hi,

Ik ben bezig met OO in PHP5 en loop tegen het volgende aan. Ik heb een abstracte klasse Dataclass die door dataclasses worden ge-extend. Nu heb ik de __get en __set in de dataclass geset en in sommige gevallen hebben child klassen een eigen __get een __set. Klopt het dat ik niet zomaar parent::__get aan kan roepen om algemene variabelen te verkrijgen? Zijn de variabelen uit de child klasse niet bekend in de scope van de parent klasse?

Hier mijn code:

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 Bestelling extends Dataclass
{
    private $id;

    /* een lading variabelen en een __constructor */

    public function __get($name)
    {
        if($name == 'materiaaloptie' && !isset($this->materiaaloptie))
        {
            $this->materiaaloptie = new Materiaaloptie($this->materiaaloptieId, array(), $this->id);
            
            return $this->materiaaloptie;
        }
        else if($name == 'materiaaloptie')
        {
            return $this->materiaaloptie;
        }
        else if($name == 'gebruiker' && !isset($this->gebruiker))
        {
            $this->gebruiker = new Gebruiker($this->gebruikerId);
            
            return $this->gebruiker;
        }
        else if($name == 'gebruiker')
        {
            return $this->gebruiker;
        }
        else
        {
            return parent::__get($name);
        }
    }
}
?>


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
<?php
abstract class Dataclass
{
    public function __set($name, $value)
    {
        $this->$name = $value;
    }
    
    public function __get($name)
    {
        if(!isset($this->$name))
        {
            $trace = debug_backtrace();
            
            throw new Exception('Undefined property via __get(): '.$name.' in '.$trace[0]['file'].' on line ' . $trace[0]['line'], E_USER_NOTICE);
            
            return null;
        }
        else
        {
            return $this->$name;
        }
    }
}
?>

Acties:
  • 0 Henk 'm!

  • Observer
  • Registratie: April 2001
  • Laatst online: 10-09 03:28
In je code voorbeeld is de member variabele '$id' gedeclareerd als private (de rest misschien ook?). In PHP zijn private variabelen aleen zichtbaar binnen de class die ze declareerd (zie: http://de3.php.net/manual/en/language.oop5.visibility.php).

Als je ze protected maakt zou het moeten werken.

[ Voor 3% gewijzigd door Observer op 28-10-2009 09:55 ]

There are 10 kinds of people in the world: those that understand binary and those that don't


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Sowieso is een isset() onnodig. Een __get magic method wordt pas getriggered op het moment dat de property niet bestaat. Hij zal dus altijd eerst proberen de property te benaderen en als dat niet lukt, gebruikt hij __get().

Dus je kan een heleboel uit je __get() slopen. Tot slot snap ik niet wat je met de parent::__get() wilt. Alleen ervoor zorgen dat de exception gegooid wordt?

Acties:
  • 0 Henk 'm!

  • Slagroom
  • Registratie: Juni 2001
  • Laatst online: 05-10-2024
de protected hielp, thanks

@mithras: als de variabelen private of protected zijn bestaan ze voor de buitenwereld toch niet en wordt de __get method toch getriggerd? Of klopt die gedachtengang niet?

Wat betreft de parent::__get() en parent::__set(): Ik wil alles zo veel mogelijk centraliseren. Zo heb ik de volledige controle over -alle- __get's en __set's. Dus mocht ik een keer iets willen doen met deze functies dan hoeft dat maar op één plek. Leek me handig...

[ Voor 5% gewijzigd door Slagroom op 28-10-2009 10:14 ]


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Slagroom schreef op woensdag 28 oktober 2009 @ 10:14:
de protected hielp, thanks

@mithras: als de variabelen private of protected zijn bestaan ze voor de buitenwereld toch niet en wordt de __get method toch getriggerd? Of klopt die gedachtengang niet?

Wat betreft de parent::__get() en parent::__set(): Ik wil alles zo veel mogelijk centraliseren. Zo heb ik de volledige controle over -alle- __get's en __set's. Dus mocht ik een keer iets willen doen met deze functies dan hoeft dat maar op één plek. Leek me handig...
Over dat private klopt inderdaad. Maar wáárom ga je dan met private/protectes aan de slag en kan je ze daarna alsnog zelf in je getters/setters zetten? "Voor de toekomst" is redelijk overkill. De magic methods kosten wat overhead en als je dat kan voorkomen zou het mooi zijn. Nu doen ze niets anders dan wanneer je ze public zou maken ;)

En tot slot nog een opmerking over je exceptions: een exception heeft al een backtrace, filename, linenumber etc. Verder als je bovenstaande in acht neemt en het laden van die properties at abstraheert, kan je het al snel omschrijven tot 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
abstract class Dataclass
{
  public function __get ($property)
  {
    throw new Exception('Unknown ' . $property . ' of class ' . get_class($this));
  }
}

class Bestelling extends Dataclass
{
  protected $_autoLoad = array('Materiaaloptie', 'Gebruiker');

  public function __get ($property)
  {
    $property = strtolower($property);
    $class = ucfirst($property);
    if (in_array($class, $this->_autoLoad)) {
      $this->$property = new $class($this);
      return $this->$property;
    }
    parent::__get($property);
  }
}

[ Voor 4% gewijzigd door mithras op 28-10-2009 10:20 ]


Acties:
  • 0 Henk 'm!

  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
Mag een Abstracte classe wel een __get hebben?

**Edit: nevermind.

[ Voor 22% gewijzigd door TJHeuvel op 28-10-2009 11:11 ]

Freelance Unity3D developer


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Waarom niet?
Pagina: 1