Magische methode __get() bij één standaardeigenschap

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Ward van der Put
Moderator

Ward van der Put

02/12/2012 14:43:28
Quote Anchor link
In mijn framework heb ik een class die maar één taak heeft: een KIX (KlantIndeX) genereren op basis van een postcode, huisnummer en optioneel huisnummertoevoeging.

De class heeft ook maar één public eigenschap: de gegenereerde KIX. Je zou intuítief zeggen dat de getter __get() geen parameter nodig heeft, maar dit eindigt in een “Fatal error: Method ...::__get() must take exactly 1 argument”:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
    /**
     * @return string
     */

    final public function __get()
    {

        return $this->kix;
    }

?>


Kan ik inkomen: de magische methode __get() verwacht de naam van het argument dat de getter moet retourneren. Ik heb het nu omzeild met $name = 'kix':

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
    /**
     * @return string
     */

    final public function __get($name = 'kix')
    {

        return $this->kix;
    }

?>


Maar ergens lijkt me dit ook niet okay. De methode retourneert altijd een KIX, ongeacht welke naam je in $name stopt. Deze methode suggereert nu bovendien dat er meer eigenschappen te halen zijn, maar er is er maar één.

Iemand suggesties voor verbeteringen?
Gewijzigd op 02/12/2012 14:45:50 door Ward van der Put
 
PHP hulp

PHP hulp

25/04/2024 18:35:38
 
Ozzie PHP

Ozzie PHP

02/12/2012 14:58:20
Quote Anchor link
Hoe wou je die magic functie dan aanroepen?

Kun je die functie niet gewoon get of getKix noemen?

$kix = new Kix();
$kix = $kix->get();
 
Ward van der Put
Moderator

Ward van der Put

02/12/2012 15:13:35
Quote Anchor link
Ozzie, een getKIX() kan uiteraard altijd nog. Ik vroeg me meer af hoe je de magische methoden __get() en __set() in dit soort situaties het beste kunt implementeren.
 
Stien ss

stien ss

02/12/2012 15:46:09
Quote Anchor link
Misschien is __invoke hier beter op zijn plaats?
 
Ozzie PHP

Ozzie PHP

02/12/2012 15:54:09
Quote Anchor link
Ward, de magic __set en __get gebruik je om variabelen te setten en getten die vantevoren nog niet in de class zijn gedefinieerd. PHP ziet dat de variabele niet is voorgedefinieerd in de class en roept dan de __get of __set functie aan. Voorbeeldje:

In je class maak je een functie __set en __get:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
public funtion __set($key, $value) {
  $this->$key = $value;
}


public function __get($key) {
  return $this->$key;
}

?>


Deze gebruik je dan als volgt:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
$kix
= new Kix();
$kix->test = 'bla bla'; // er wordt nu in de class een property geset met de key test en de waarde bla bla.
echo $kix->test; // de __get functie wordt aangeroepen en op het scherm verschijnt 'bla bla'.
?>


Beetje duidelijk zo?
 
Wouter J

Wouter J

02/12/2012 15:55:59
Quote Anchor link
Ward, een publieke property gaat nooit via de __get() method, dus dit is nu een beetje een vreemd script. Tevens ben ik benieuwd hoe jij verwacht de __get() aan te roepen?
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
$obj
= new FooObject();
$obj->foo; // roept FooObject::__get('foo') aan
?>


Tevens zal je scriptje nu ook nooit kunnen werken, je zet je default value nu op een waarde, maar aangezien de __get() method altijd al een argument krijgt wordt de default waarde nooit gebruikt.

Stien, __invoke vind ik al een stuk beter, alleen denk ik niet dat ward hiernaar opzoek is. Ik denk dat Ward __toString() wilt:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
class A
{
    public $foo = 'Hello World';
    
    public function __toString()
    {

        return $this->foo;
    }
}


$a = new A();
echo $a; // >> 'Hello World'

$b = (string) $a;
echo $b; // >> 'Hello World'

$c = strtolower($a);
echo $c; // >> 'hello world'
 
Ward van der Put
Moderator

Ward van der Put

02/12/2012 16:11:55
Quote Anchor link
Wouter, dank je, dat is het! Ik had hier inderdaad __toString moeten gebruiken.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.