Category: PHP OOP

Directory Iteration With DirectoryIterator() In PHP 5

26 September, 2008 | PHP OOP | No comments

The normal way of looping through a directory is to get a handle on the directory, then go through each item, making sure that the file is readable and is not "." or ".." before doing something with the file. Because this is done a lot the DirectoryIterator() object was created in PHP5 to simplify this process.

The constructor of the DirectoryIterator() object takes a single parameter, this is the path of the directory that is to be iterated over.

$dir = new DirectoryIterator('/');

To get the current working directory you can use the PHP function getcwd(). This will return the directory that the PHP script is being run from.

$dir = new DirectoryIterator(getcwd());

The previous bit of code will open up the root directory of your server. If you are on a Linux server you will see directories like dev, var, srv, etc, lib, home, root, sbin and usr.

With the object now created there are some different functions that can be used to look at different things. Here is a small list of what can be used:

  • isDot(): This function is used to see if the file is a "." or a "..".
  • isReadable (): Checks if the file is readable. If it is then it returns true, otherwise it is false.
  • next(): Moves the iterator onto the next item in the list.
  • valid(): This function checks to see if there is anything in the directory that can be iterated over. Basically, this function returns false if the iterator is at the end of the directory.
  • current(): Returns the name of the current file.

These functions can be put together in the following way. This snippet of code will print out all of the files in a directory.

while($dir->valid()){
 if(!$dir->isDot()){
  print $dir->current()."<br />";
 }
 $dir->next();
}

The Final Keyword In PHP5

14 April, 2008 | PHP OOP | No comments

PHP5 allows you to stop classes being extended or to stop child classes overwriting functions.

The first way to use the final keyword is to stop child classes from overwriting functions when they are created. This can be used to stop an important function from being overwritten. To use the final keyword here just add it to the start of function name.
class ParentClass{
 final public function importantFunction() {
  echo 'ParentClass::importantFunction()';
 }
}
 
class ChildClass extends ParentClass{
 public function importantFunction() {
  echo 'ChildClass::importantFunction()';
 }
}
 
$child = new ChildClass();
$child->printString();

Attempting to override this function will produce the following error.
Fatal error: Cannot override final method ParentClass::importantFunction() in test.php on line 12

The second way to use the final keyword is to stop child classes from being created. This can be useful if you have a security class that you want to keep as the final version. To use the final keyword like this just append it to the class name.
final class ParentClass{
 public function importantFunction() {
  echo 'ParentClass::importantFunction()';
 }
}
 
class ChildClass extends ParentClass{
 public function importantFunction() {
  echo 'ChildClass::importantFunction()';
 }
}
 
$child = new ChildClass();
$child->printString();

Attempting to override this function will produce the following error.
Fatal error: Class ChildClass may not inherit from final class (ParentClass) in test.php on line 12

Sinlgeton Design Pattern With PHP5

9 February, 2008 | PHP OOP | No comments

The singleton design pattern is used to centralise an object in an application that is used to store changing variables that can then be accessed by other parts of the program. It allows only the single instantiation of an object, hence the name.

The main use of a singleton is to create an alternative to the use of global variables. Although global variables are useful they can lead to a major problem if you happen to assign two variables with the same name, PHP generates no errors and your program will start to act oddly. This might not be a problem in small programs, but in larger systems it is very easy to have global variable clashes.

The singleton pattern gets around this by using an single object that is accessible to any part of the program that wants it. If two classes are declared with the same name PHP throws an error so if another part of the program tries to use the same class name you will know about it.

Another use of a singleton is to coordinate actions across a system. If two parts of a system use the same object a singleton can be used to stop the different parts of the system creating separate objects. With a singleton only a single object is ever created.

The first step in creating a singleton is to create the class in the usual form, but to make the constructor private. This means that it is not possible to instantiate the class directly. Next we set up a static variable and a static function, their static nature means that they are available even if the object is not instantiated.

The static variable is used to store an instance of the object. When the static function is called it checks to see if an object is held within the static variable, if it is then it returns that object, if it doesn’t then a new object is created and returned. Here is some sample code of a class that can be used to store a single preference.

class Preferences{
  private $property;
  public static $instance;
 
  private function __construct(){}
 
  public static function getInstance(){
    if(empty(self::$instance)){
      self::$instance = new Preferences();
    }
    return self::$instance;
  }
 
  public function setProperty($value){
    $this->property = $value;
  }
 
  public function getProperty(){
    return $this->property;
  }
}

This class is used in the following manner.

$pref = Preferences::getInstance();
$pref->setProperty("nothing");

A more useful class is one that stored many different types of property as an array.

class Preferences{
  private $property = array();
  public static $instance;
 
  private function __construct(){}
 
  public static function getInstance(){
    if(empty(self::$instance)){
      self::$instance = new Preferences();
    }
    return self::$instance;
  }
 
  public function setProperty($key,$value){
    $this->property[$key] = $value;
  }
 
  public function getProperty($key){
    return $this->property[$key];
  }
}

This is used in the following manner.

$pref = Preferences::getInstance();
$pref->setProperty("property1",nothing");

Due to the use of the get and set methods within the object Singletons cannot be overwritten with the wrong kind of data, which provides a further level of protection over the standard global variable.

It is very easy to use the singleton pattern in everything that you do, but it should be used only when you really need it. If something goes wrong with your program you can have a hard time in spotting what it is due to the difficulty of tracing relationships in a system build with singletons.