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;;


5 Comments

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.

Marcelo Gornstein on Saturday, February 19, 2011 (8:22PM)

You might also like to try ding, at http://marcelog.github.com/Ding which is modeled after Spring(tm) for java, it has a complete inversion of control and dependency injection container, and aop. It also supports some of the jsr 250 and 330 annotations

Dimyanshan on Sunday, January 08, 2012 (11:11AM)

привет

Spirit on Tuesday, April 24, 2012 (10:34AM)

Auto-create get and set function is not a Java limitation. I can implement it by reflection in the same method. I create set and get method by heand (or by IDE) because It’s very expensive in terms of time and performance and I have no controll of witch variables are inside beans.

Tiago on Friday, August 09, 2013 (9:23PM)

I liked.