Archive for December, 2009

How to prevent setting dynamic fields in your PHP classes

One problem that could arise when multiple coders are working on the same project is that everyone might not work with the same editors, and therefore everyone might not have intellisense / autocompletion. What could this cause? Alot of things 🙂 But we’ll talk about one of them below.

Well all PHP classes are by nature dynamic, which means that it’s possible to set variables that havn’t been declared. One would believe that setting the class to “final” would automatically fix this, but this is not the case.

Simple example:

class SimpleStructure 
{
	public $name;
	public function __construct( $name ) {
		$this->name = $name;
	}
}
 
$simple = new SimpleStructure("nonobtrusive");
$simple->myName = "dynamic_value";	//allowed
 
echo $simple->name, " - ", $simple->myName;

The above code will output:

nonobtrusive - dynamic_value

So, how can we prevent this if it’s an unwanted behaviour ?
The answer is simple, use the magic method __set.

class SimpleStructure 
{
	public $name;
 
	public function __construct( $name ) {
		$this->name = $name;
	}
 
	public function __set( $key, $value ) {
		throw new Exception( "Not allowed to assign undefined variable : " . $key );
	}
}
 
$simple = new SimpleStructure("nonobtrusive");
$simple->myName = "dynamic_value";	//allowed
 
echo $simple->name, " - ", $simple->myName;

The above code would throw the error:

Fatal error: Uncaught exception 'Exception' with message 'Not allowed to assign undefined variable : myName'

To wrap this up we could also create our own UndefinedFieldException class and throw an instance of it to easier catch that specific error.

class UndefinedFieldException extends Exception
{
	public function __construct( $key ) {
		$this->message = "Not allowed to assign undefined field : " . $key;
	}
}
 
//then we can throw the exception like this instead
throw new UndefinedFieldException( $key );
 
//which in the above example would show as
Fatal error: Uncaught exception 'UndefinedFieldException' with message 'Not allowed to assign undefined field : myName'

, , , , ,

1 Comment