My last article discussing the current status of PHP's internals was quite well read so it is time for another update. Today I will be discussing a feature that at this moment is called "Property Accessor". It is a method of defining getters and setters. Originally an RFC was defined as early as september 2009, but recently new discussion took place and an actual patch was created. There is no certainty this feature will ever make a PHP version but discussion seems to target implementation details and not the feature itself, so things are looking bright for this feature.

I took this specific topic on the internals list because it deals with something totally new and because it is well documented and discussed. What I would like to do is explain the new feature and hopefully start a discussion regarding the feature outside the internals list itself. I'd like to see what the userland thinks of this feature.

PHP''s pet. Every now and then an Elephpant image is required :)

I'll explain the feature and give some examples, but the RFC is very well written and I won't cover all of it. If you'd rather read the RFC itself, visit the original RFC here and an RFC for the current patch implementing properties here. Be sure to come back and post your feelings about it though.

This article uses syntax that corresponds to the second RFC, describing how the current patch is implemented.

What are properties?

If you're still here lets first establish what properties are (at least for the sake of the RFC):

Properties provide a clean, easy to understand, and unified syntax for get/set accessors. They allow incoming and outgoing requests (gets and sets) from a class member to be run through a method first. This method can perform validation or a transformation, or update other areas of the class. Properties do not even have to be associated with a class member, and can generate their own data on-the-fly.

The way PHP currently solves this is using the magic __get and __set methods:

class Period { private $seconds; public function __set($name, $value) { switch ($name) { case "minutes": $this->seconds = $value / 60; break; case "hours": $this->seconds = $value / 3600; break; } } public function __get($name) { switch ($name) { case "minutes": return $this->seconds * 60; break; case "hours": return $this->seconds * 3600; break; } } }

It is easy to see how this would get cluttered and cumbersome with large classes. Apart from this maintanence hell it is also a possible way of breaking inheritance. If a child class overloads the __get and __set methods this can alter properties of the class which you would not expect from a child class.

The RFC we're dealing with today offers a different way of solving this problem:

class Period { private $seconds; public minutes { get { return $this->seconds / 60; } set { $this->seconds = $value * 60; } } public hours { get { return $this->seconds / 3600; } set { $this->seconds = $value * 3600; } } }

The code snippet above introduces a new concept called "property". The get and set keywords define the respective accessors. If you're wondering where $value came from, it is the variable that is incoming from the "set" call and is "magically" accessible. The syntax above would work like the magic __get and __set do, enabling the following code snippet to work:

$Period = new Period(); $Period->minutes = 10;// stored in $this->seconds as 600 $Period->hours = 10;// stored in $this->seconds as 36000 echo $Period->minutes;// outputs 10 echo $Period->hours;// outputs 10

Read-only and write-only accessors

Now that the basic syntac is clear I would like to look at properties that are either read-only or write-only. The second RFC dealing with the current actual implementation only provides a single way, using a keyword. The original RFC also provided an implicit way, I'll show both:

class Period { private $seconds; //implicit read-only public minutes { get { return $this->seconds / 60; } } //keyword read-only public read-only hours { get { return $this->seconds / 3600; } } }

Here I like the implicit method best, a property is simply read-only because there is no set keyword present. I also really dislike the - in the read-only keyword. It may be proper english, but it seems akward in code to me. Ofcourse the same rules that apply to the above read-only example apply to write-only properties as well.

Other features

As I already wrote, I won't be covering all of the RFC, I mainly hope to see a discussion starting here. I do want to name some other features the properties RFC will bolster however:

Asymmetric Accessor Accessibility (i.e.: a protected get and a public set for a property)

Interface properties (Interfaces may declare properties with empty get and set methods. In this way the interface forces implementing classes to define the property)

Static properties (self explanatory I presume)

Trait support

and more....

Conclusion

I personally like this feature. I don't really know if it is much better than defining the getSomething and setSomething methods without the language specific syntax, but it is thought trough, well described and a patch is already there. For me this kind of stuff is the reason to follow the internals list :)

Once again, I am very curious to your opinion, so don't hesistate to give it!

Share this post!