> It has more to do with problems with encapsulation and visibility.
> Frederik made a nice summary of that, he will reply here:
Ok, here goes:

The way I see it properties in PHP should do the following:

1. Make it possible to override behavior when accessing properties
2. easy access to properties (through -> for example)
3. make it possible to give constructive feedback when programmers uses 
a property in the wrong way
4. Well defined control over when setters and getters are used and when 
they are not.
5. The possibility to use the normal visibility rules as for other class 
variables.

Now, the __set and __get functionality almost conform to the above 
requirements. 1 & 2 are already covered, AFAIK 3 has been discussed and 
a good solution has been found to this. The only problems we have left 
are 4 and 5.

Let me illustrate problem 4 with an example:

class A {
  private variable; // some property
  public function test() {
    $this->variable = 42;
  }
}

In this case the variable would be set directly in the test method. This 
is not desirable since it is unclear when the setters and getters are 
called and when you are actually setting the variable directly or not. 
Basically you want the setters and getters to be run except when 
explicitly setting the variables. This problem becomes even more 
evident in the following example:

class A {
  protected variable; // some property
}

class B extends A {
  public function test() {
    $this->variable = 42;
  }
}

In this example the variable would still be set directly (not using the 
set and get methods). Using the current implementation you could fix 
this case by setting the variable to private. This brings us to the 
next issue: using the current implementation it is not possible to have 
private or protected properties.

class A {
  private variable; // some property
  public function test() {
    $this->variable = 42;
  }
}

As you can see, the variable (in fact) is not private at all. It is 
public. Hence there is a mismatch between what you declare and what it 
actually is. Setting a property to be public doesn't make sense at all 
since the __set and __get function will not be called then.

Here is a possible way to solve these two interconnected problems:

class A {
  private property priv_prop;
  protected property prot_prop;
  public property pub_prop;
  
  // very simplified implementation
  function __set( $name, $value ){
    $this->properties[$name] = $value;
  }  

  public function test() {
    // private property, we have access
    $this->priv_prop = 42;
  }
}

function somewhere() {
  $a = new A();
  // private property, not allowed
  $a->priv_prop = 42;
  // public property.. ok
  $a->pub_prop = 42;
}

The way this works is that when a property is declared the __set and 
__get is *always* run when accessing it unless you don't have access to 
that property of course.
Similarly you could also use the protected property in subclasses. Using 
an implementation like this, the property keyword does nothing but 
declare the existence of a property with this name. The actual storage 
of the property data must be done somewhere else, e.g in a private 
member variable. It would of course be even better if the property 
declaration also declared a variable. However, then we need an explicit 
way of setting them since we still want __set and __get to be called 
for private properties.
In addition to solving both problems this solution with explicit 
property declaration also makes it easy to document the properties of a 
class.

Cheers,
Frederik
-- 
Frederik Holljen
Head of development
[EMAIL PROTECTED] | eZ systems | ez.no

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to