Home > PHP, Proof-of-concepts > Properties in PHP – revisited

Properties in PHP – revisited

January 14th, 2009 Leave a comment Go to comments

A while ago I was daydreaming about native property support in PHP. Unfortunately it will be a while before PHP itself will support this natively and an even longer while before shared hosting providers will upgrade to a newer version of PHP.

So what’s the big deal about those properties? In short, they make a developers life easier by allowing the developer to code no more than needed at that moment. And lets face it… less code is better! In this post we’ll see that it’s not impossible to enjoy properties in PHP today. As with a lot of good things, it does come with a small price though…


Lets have a look at a use-case to demonstrate where properties will not only save you time, but it will also save your sanity. In this example we’re modeling a Person class. In the beginning of the project, the requirements for the Person class are quite simple: a Person has an age and a name. In the simplest form we can code that as follows:

<?php
class Person
{
    public $age;

    public $name;
}

This look easy enough, and it is. It even works like a charm and it’s possibly the fastest implementation for the Person class.

But, pesky as they are, the client suddenly wants some logic added to our Person class! A Person suddenly can’t be younger than 21 years old. This poses a problem. To add logic to our Person class, we would have to switch the public age attribute with a pair of getters and setters:

<?php
class Person
{
    private $_age = null;

    public $name = null;

    public function getAge()
    {
        return $this->_age;
    }

    public function setAge($age)
    {
        if ($age < 21) {
            throw new Exception('You need to be at least 21 years or older!');
        }

        $this->_age = $age;
    }
}

Technically this works like a charm, however it will force me to go through my entire application and switch all references from the public attribute to the getter and setter. Not an ideal situation. One possible solution is to do things the Java way: just create all getters and setters up-front so you don’t have to do so afterwards. Even though this works fine, it’s in violation of our mission to write no more code than we actually need at the moment of writing.

The solution? Properties! But wait… PHP doesn’t support those, remember? Luckily we still have magic methods. It’s nowhere near as nice as a native solution, but at least it helps us write no more code than we need at the moment we’re first writing our code:

<?php
abstract class ModelAbstract
{
    public function __get($key)
    {
        $method = 'get' . ucfirst($key);

        if (!method_exists($this, $method)) {
            throw new Exception('No property found for ' . $key);
        }

        return $this->$method();
    }

    public function __set($key, $value)
    {
        $method = 'set' . ucfirst($key);

        if (!method_exists($this, $method)) {
            throw new Exception('No property found for ' . $key);
        }

        $this->$method($value);
    }
}

We’ll take a look at what this does exactly later. The important thing to note is that we can now do the following:

<?php
class Person extends ModelAbstract
{
    private $_age = null;

    public $name = null;

    public function getAge()
    {
        return $this->_age;
    }

    public function setAge($age)
    {
        if ($age < 21) {
            throw new Exception('You need to be at least 21 years or older!');
        }

        $this->_age = $age;
    }
}

$person = new Person();

try {
    $person->age = 10;
} catch (Exception $e) {
    // Will print "You need to be at least 21 years or older!"
    echo $e->getMessage();
}

With this construction in place, we can safely switch from a public attribute to getters and setters, without changing the rest of the application code. The only real downside to this – aside from the minor speed impact – is the fact that you have to subclass ModelAbstract to make this work. Luckily it’s not a lot of code, so should there be a big need to get rid of the ModelAbstract inheritance it’s not a big disaster to do some copy/paste work.

This method works by assuming you have get- and set methods that have the same name as the property you’re trying to access. When there’s a public attribute, it will use that. If there’s no public attribute, it will fall back to __get or __set and the logic will take it from there.

All of this is just a proof-of-concept of implementing properties in PHP and of the way I want to be using properties to access data the data in my objects. Please comment your experiences with this approach or similar approaches. I’m curious to see how practical this solution would be in a real-life situation.

Categories: PHP, Proof-of-concepts Tags:
  1. No comments yet.
  1. No trackbacks yet.