PHP doesn’t offer much in the way of read-only member variables, so when you need one, you have to make the variable private, and define a getter method. This is all well and good, but what if your class has dozens of member variables? The class size grows quite quickly.

To solve this, I’ve written setter/getter methods that are all-purpose. You can use them to access all the variables in your class. Here’s a sample class that employs them:

class MyClass{
	// Member variable visibility
	private $readonly = array('myVar');
	private $noaccess = array('foo');
 
	private $myVar = true;
	private $foo = 'Hello';
	private $bar = '';
 
	/**
	* __construct()
	*	Description:
	*		Object constructor. 
	*	Parameters:
	*		none
	*	Returns:
	*		void
	**/
	public function __construct(){}
 
	/**
	* __set()
	*	Description:
	*		Setter method for class variables.
	*	Parameters:
	*		$key - the member variable name.
	*		$value - the new value.
	*	Returns:
	*		void	
	**/
	private function __set($key, $value){
		// Check to see the member variable exists in this class.
		if (array_key_exists($key, get_class_vars(__CLASS__))){
			// The member variable exists.
 
			// Check to see if the variable is read only.
			if (! in_array($key, $this->readonly)){
				/* This is where the variable gets   
				set. If any code needs to get executed 
                                when the variable is set, do it here. */			
				switch ($key){
					case 'bar':
					  $this->$key = strtoupper($value);
					  break;
					default:
					  // Other variables are set this way.
					  $this->$key = $value;
				}
 
			}else{
				// The variable is read only.
				throw new Exception('Variable is read only');
			}
		}else{
			// The variable does not exist.
			throw new Exception('Variable does not exist.');
		}
	}
 
	/**
	* __get()
	*	Description:
	*		Getter method for class variables.
	*	Parameters:
	*		$key - the member variable name.
	*	Returns:
	*		mixed - the value of the member variable requested.
	**/
	private function __get($key){
		// Check to see that the member variable exists.
		if (array_key_exists($key, get_class_vars(__CLASS__))){
			// The member variable exists, see if it's visible.
			if (!in_array($key, $this->noaccess)){
				return $this->$key;
			}else{
				throw new Exception('Variable is private');
			}
		}else{
			throw new Exception('Variable does not exist.');
		}
 
	}
 
	/**
	* hello_world()
	*	Description:
	*		Guess...
	*	Parameters:
	*		none.
	*	Returns:
	*		void.
	**/
	public function hello_world(){
		echo $this->foo . ' ' . $this->bar;
	}
}

It might look a bit complicated, but the idea is really simple once you understand PHP’s __get() and __set() magic functions. These functions are called whenever a member variable is accessed. This allows you to write code that gets executed each time this happens.

In the __get() example above, I check to see if the variable name passed in actually exists in the class, and if it does, I check to see if it’s in the $noaccess array. If the variable is in the $noaccess array, then an exception is thrown stating that the variable isn’t accessible, otherwise, the value is returned.

In the __set() example, I also check to see if the variable name passed is in the class, and if it is, I check to see if it’s in the $readonly array. If it is, an exception is thrown saying the variable is read-only. If the variable is not read-only, then the variable is set.

The __set() function also allows you to modify what happens when setting a variable. In the example above, when the variable $bar is assigned a value, the __set() function is instructed to convert the value to uppercase before storing it. All other variables are stored as is.

I’ve only just written these functions, and I haven’t used them enough to find any short-comings. If you use this code, or modify it to suit your needs, please give me credit, and let me know what you’ve done. I’m always interested to see how my code is being used.

Happy coding!