PHP5 BetterAccess class

So I was working on a little framework for a mini application I'm going to build soon and I decided to use object overloading because it's written in PHP5. If you haven't used the overloading functions in PHP5, they are: __get, __set, __isset, and __unset. You can read more about them on PHP's overloading page.

As I've said, this is a PHP5 framework and so I decided to make use of the ArrayAccess interface. However, I haven't actually used this interface in a while and forgot the actual functions that it requires: offsetGet, offsetSet, offsetExists, and offsetUnset. Intuitively, I thought that it must use the overload functions (__get, et al.) and so programmed everything assuming that. Unfortunately when I actually got around to test everything, there were errors. At first I decided to go in and make the minor name switches, but it being a framework, I decided if anyone but me were using it, I could have a better solution. Vague enough? Here's the nifty little BetterAccess class I came up with:

abstract class BetterAccess implements ArrayAccess {
	abstract public function __get($key);
	abstract public function __set($key, $val);
	abstract public function __isset($key);
	abstract public function __unset($key);
	
	final public function offsetGet($key) {
		return $this->__get($key);
	}
	final public function offsetSet($key, $val) {
		return $this->__set($key, $val);
	}
	final public function offsetExists($key) {
		return $this->__isset($key);
	}
	final public function offsetUnset($key) {
		return $this->__unset($key);
	}
}

Not sure what the point of this is? Let me show you:

class Foo extends BetterAccess {
	private $vars = array();
	
	final public function __get($key) {
		$ret = NULL;
		if(isset($this->vars[$key]))
			$ret = $this->vars[$key];
		return $ret;
	}
	final public function __set($key, $val) {
		$this->vars[$key] = $val;
	}
	final public function __isset($key) {
		return isset($this->vars[$key]);
	}
	final public function __unset($key) {
		unset($this->vars[$key]);
	}
}
$foo = new Foo;

$foo['bar'] = 'hi';
$foo->baz = 'hello';

echo $foo->bar;
echo $foo['baz'];

// Output: hihello

This might not seem immediately useful; however, the point of it is taste. Depending on your coding preferences, BetterAccess allows you to access a class either through overloading or using array access.

Comments

Thank you for that great article. What is the difference between the following code and yours?

class Foo {

private $vars = array();

public function __get($key) {

$ret = NULL;

if(isset($this->vars[$key]))

$ret = $this->vars[$key];

return $ret;

}

public function __set($key, $val) {

$this->vars[$key] = $val;

}

public function __isset($key) {

return isset($this->vars[$key]);

}

public function __unset($key) {

unset($this->vars[$key]);

}

}

I do not understand the advantage of using BetterAccess.

Thank you in advance for your answer

Best regards,

Tim

    by tim on Jul 18, 2007 @ 8:14am

The difference is that the betteraccess (I call it just an overloard class now) class implements ArrayAccess and so can also be accessed as if it were an array. With your code, I would only be able to do this:

$foo = new Foo;

$foo->bar = 'hello';

echo $foo->bar;

One of the first major differences is that I don't define a Foo::$vars array to hold any data so the class itself has no functionality. That is why it is abstract.

The point of it was to make it so that any class that extends it only needs to make the four overload functions that you have used and implement them in whatever way they wish.

Once they've implemented the overload functions, as you have, then they can now access the class as if it were an array or an object. So, for example, if I changed your code a bit..

class Foo extends BetterAccess {

// ...

}

$foo = new Foo;

$foo->bar = 'hi';

// both are equivalent

echo $foo->bar;

echo $foo['bar'];

    by Peter Goodman on Jul 18, 2007 @ 9:01am

Add a Comment