Bean Pattern in PHP5


Taking advantage of PHP5’s magic methods __get, __set, and __call, the bean pattern can be implemented pretty easily in PHP. Here’s an example of it in Java:

public class UserBean {

    protected String username, email, location;

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }

    public String getLocation {
        return location;
    }
    public void setLocation(String location) {
        this.location = location;
    }
}

One of the annoyances of this (at least for me) is that you end up creating a bunch of getter/setter methods that don’t do anything special – they either return the encapsulated variable or set it. So, I wrote a base class that uses PHP5’s magic methods to take care of all of those generic getters and setters.

abstract class Bean {
    public function __call($name, $arguments) {
        if (strpos($name, 'get') === 0) {
            $property = strtolower(substr($name,3,1)) . substr($name,4);
            return $this->$property;
        }
        elseif (strpos($name, 'set') === 0) {
            $property = strtolower(substr($name,3,1)) . substr($name,4);
            return $this->$property = $arguments[0];
        }
        else {
            throw new Exception("Method $name does not exist");
        }
    }

    public function __get($name) {
        $getter = 'get' . ucfirst($name);
        if (method_exists($this, $getter)) {
            return call_user_func(array($this, $getter));
        }
        return $this->$name;
    }

    public function __set($name, $value) {
        $setter = 'set' . ucfirst($name);
        if (method_exists($this, $setter)) {
            call_user_func(array($this, $setter), $value);
        }
        else {
            $this->$name = $value;
        }
    }
}

Using the above abstract class, the example UserBean in PHP would become just:

class UserBean extends Bean {
    protected $username, $email, location;
}

And you can access the bean as follows, without having to write any of these functions:

$user = new UserBean();
$user->setUsername('Jim');
echo $user->getUsername();

If you needed to do any additional work in the getter function, you can just create a getter function like you normally would:

class UserBean extends Bean {
    protected $username, $email, location;
    public function getUsername() {
        return "User: $username";
    }
}

In addition, if you want cleaner syntax (i.e. when mixing PHP with your HTML), you could also access properties of the bean directly, and the getter/setter functions will be called automatically if they exist. Since the properties are “protected”, attempts to access the properties will get routed to the __get and __set functions, where it will attempt to call a getter/setter if it exists.

$user = new UserBean();
$user->username = 'Jim';
echo $user->username;;


One Comment

Linkamp on Tuesday, April 20, 2010 (11:48AM)

Nice, i like java and your patterns. Actually i work in a php project with Zend Framework. I use this for model beans.