Home > Code > Phramework class & extending the define function

Phramework class & extending the define function

The core of the framework will be focused around a single object, an instance of the Phramework class. Admittedly, this first post regarding the class is quite tedious however it is nonetheless quite essential.

As this Phramework object is representative of a single request there should only ever be one such instance per Apache process, thus Phramework should implement the singleton pattern. The singleton code is an exact copy of that provided by the PHP documentation and results in object instantiation by:

$p = Phramework::singleton(); //returns the same instance no matter where it is called from
$p = new Phramework(); //triggers an error as the Phramework constructor is private

Before developing the functions to handle the page requested via the .htaccess RewriteRules there is some basic functionality that needs to be implemented for storage of data. Particularly, the define function needs to be reworked in order to allow values other than scalars (null, integer, string, float and boolean), such as arrays and objects, to be stored. This will be useful later on for security reasons as we will only define “clean” values.

In order to do this, we rely on the PHP magic methods __set() and __get()1. These methods are called when there is an attempt to declare (__set) or retrieve (__get) an attribute of an object that has not been explicitly declared2. As we are extending the define function we need to declare two arrays; the first for storage of values and the second for storage of “locked” keys.

private $values = array();
private $locked = array();

Before attempting to save a value into the $values array, __set will first check that the key is not in the $locked array. Return values mimic the standard PHP define function.

public function __set($key, $val){

//Check for no locking before saving
if(!in_array($key, $this->locked)){

$this->values[$key] = $val;
return true;

}
return false;

}

With this check in place, all that is needed is a function to lock a particular key (note that a key should not be able to be unlocked so we don’t define the corresponding function).

public function lock($key){

if(!in_array($key, $this->locked)){

$this->locked[] = $key;

}

}

Now comes the final step, the extended define function. Technically this is just a convenience wrapper for setting a value and then locking it. Once again, return values should mimic those of the original PHP define function. In the event that we are defining a value and it already exists but is not locked, I have decided to trigger a warning as a courtesy.

public function define($key, $val){

//Overwriting?

if(isset($this->values[$key]) && !in_array($key, $this->locked)){

trigger_error(“Value of Phramework::{$key} is being overwritten by Phramework::define()”, E_USER_WARNING);

}

if($this->__set($key, $val)){

$this->lock($key);
return true;

}

return false;

}

Note that if the value is already locked then __set() will return false and so too will Phramework::define().

With these basics in place we are able to move on to the first interesting method Phramework::findRequestedPage() which will be discussed in the next post.

Current text version of Phramework.php

1 I believe that having all methods and attributes of the Phramework class being static would provide a better solution than the singleton pattern described above but these two magic methods cannot be declared statically.

2 While their use in this case is simple, later in the project I will demonstrate a more complex and particularly useful implementation of __set and __get with regards to database access.

Advertisement
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.