Versio

Read-only properties/fields

Overzicht Reageren

Merijn Venema

Merijn Venema

30/01/2012 21:24:06
Quote Anchor link
Beste leden,

Is het in PHP mogelijk om velden ( properties ) als read-only in te stellen? Althans, om toegang tot te krijgen. Je hebt dus wel een Setter() nodig maar geen Getter(), dat je dus gewoon $object->property kunt gebruiken. Het enige is dan dat je dus niet: $this->property = new SomeObject(); kunt doen. Daar zou je dus de Setter() voor moeten gebruiken.. Iemand een ideetje?
 
PHP hulp

PHP hulp

25/05/2012 14:11:40
Gesponsorde koppelingen:
BHosted Hosting al vanaf € 1,- per maand

Controleer nu gratis jouw domeinnaam:

  
 
- Jim  -

- Jim -

30/01/2012 22:36:45
Quote Anchor link
De property/fied private maken, en alleen een setter gebruiken.

Je bovenstaande bericht is wat verwarrend..
Merijn Venema op 30/01/2012 21:24:06:
Is het in PHP mogelijk om velden ( properties ) als read-only in te stellen? Althans, om toegang tot te krijgen. Je hebt dus wel een Setter() nodig maar geen Getter(), dat je dus ...
Gewijzigd op 30/01/2012 22:46:22 door - Jim -
 
Merijn Venema

Merijn Venema

30/01/2012 22:39:26
Quote Anchor link
Ja dat werkt natuurlijk niet. Als iets private is is het niet buiten de klasse toegankelijk.

$object = new Object();

// moet wel kunnen
echo $object->property;
// moet niet kunnen
$object->property = "Some value";
 
- Jim  -

- Jim -

30/01/2012 22:44:00
Quote Anchor link
Ja, nee....

ik bedoel:

Een private property maken, en een getter:
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
20
21
<?php
class SomeClass {
    
    // The property private
    private $prop;
    
    // CTor
    public function SomeClass($propVal)
    {

        // Set the property in the constructor
        $this->prop = $propVal;
    }

    
    // GETTER
    // Get the value or prop

    public function GetProp()
    {

        return $this->prop;
    }
}

?>
Gewijzigd op 30/01/2012 22:46:43 door - Jim -
 
Merijn Venema

Merijn Venema

30/01/2012 22:46:50
Quote Anchor link
Ja maar zoals ik het bedoel is dat een property dus read-only is. Buiten een getter om toegankelijk. In bijvoorbeeld C# kun je handig en snel Getters en Setters maken die te benaderen zijn als properties. Voordeel? Het scheelt 2 haakjes en het oogt netter.

$object->GetProperty() is minder mooi als $object->property. Enige nadeel is dat de property dus ook te overschrijven is op die manier. In een Set methode kun je nog wat feitjes controleren etc, maar hier is het gewoon klats-boem hupakee, overschrijven.
 
Jelle -

Jelle -

30/01/2012 22:53:59
Quote Anchor link
Misschien dat je de magic __get en __set kunt overloaden:

http://php.net/manual/en/language.oop5.overloading.php

Ik denk dat je daar wel wat mee kunt, zie voornamelijk example #1
 
Merijn Venema

Merijn Venema

30/01/2012 22:56:08
Quote Anchor link
Ah kijk, ik had al een grijs vermoeden. Maar is dat niet vrij traag? __get en __set zijn toch een beetje no-go methodes om te overloaden?
 
Kees Schepers
Moderator

kees Schepers

31/01/2012 09:19:46
Quote Anchor link
__get en __set traag? Dat is dan net zo traag als getPropertyName(). En deze magic methods zijn JUIST om te overloaden :)

Maar als je van een C/C++ achtergrond oid komt dan zullen 'magic methods' je wel vreemd klinken inderdaad, PHP is zowat de enige taal die zoiets implementeert.
 
Merijn Venema

Merijn Venema

31/01/2012 21:18:28
Quote Anchor link
Oke, dus eigenlijk is het vrij veilig om te implementeren? Heb het al even toegevoegd:

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

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


?>
 
Wouter J

Wouter J

31/01/2012 21:30:17
Quote Anchor link
Je moet dan wel controleren of iets een read-only propertie is of niet (ik neem aan dat je niet alleen read-only properties hebt) en anders een Exception gooien:
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
20
<?php

class Example
  protected $foo;
  protected $ro_bar;

  public function __get( $name )
  {

    $name = ( substr($name, 0, 3) !== 'ro_' ? 'ro_'.$name : $name );
    if( isset($this->$name) )
      return $this->$name;
    else
      throw new LogicException('You don't have permission to get the propertie '.$name);
  }
}


$example = new Example;
$example->foo; // throw exception
$example->bar; // give the value of bar
?>

Is wel een lelijke methode, maar ik zou niet weten hoe je het anders moet implenteren.
Gewijzigd op 31/01/2012 21:32:03 door Wouter J
 
Merijn Venema

Merijn Venema

31/01/2012 21:33:57
Quote Anchor link
Hmm goed punt. Ja ik denk dat je inderdaad nog iets nodig moet hebben dat er voor zorgt dat het als een read-only property hanteerbaar is... Aan de andere kant.. Nee, je hebt gelijk. Misschien is het sowieso beter om gewoon getters te hanteren. Ik zie de bui we hangen dat je straks wachtwoorden of sleutels in je object opgeslagen hebt met een private modifier en ze toch leuk uit kunt lezen..

Hmm hier moet wat op te verzinnen zijn. Misschien een _ op het einde?
Gewijzigd op 31/01/2012 21:35:03 door Merijn Venema
 
Wouter J

Wouter J

31/01/2012 21:54:45
Quote Anchor link
Ik heb het nu geprobeerd met een ro_ in het begin (van read only). Maar misschien moet je nog een extra propertie aanmaken met de read only properties erin, of een var in de get functie:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php
public function __get( $name )
{

  $readOnlies = Array('foo', 'someVar');
  if( in_array($name, $readOnlies) )
    return $this->$name;
  else
    throw new InvalidArgumentException(sprintf('Property(%s) not read only', $name));
}

?>
Gewijzigd op 31/01/2012 21:55:23 door Wouter J
 
Merijn Venema

Merijn Venema

31/01/2012 21:59:25
Quote Anchor link
Ja ik had het door, maar vond dat iets te lelijk om door te voeren. Een underscore op het einde is ook niet mooi, maar valt nog wel te hanteren, enige wat je hoeft te doen is een extra character toevoegen.

Maar een array bijhouden is misschien ook nog wel iets. Jammer dat we geen keywords hebben die niet nodig zijn en kunnen hanteren en vervolgens checken of een property van type xx is... Ik denk dat ik voor een array ga. Enige nadeel is echter dat door het overloaden van de __get() je niet dynamisch velden kunt toevoegen en op kunt vragen, aangezien je niet dynamisch.. shit.. ik ben echt dom van tijd tot tijd..
 



Overzicht Reageren

Get Adobe Flash player