Using Directory Iterators to Build Loader Apps in PHP

Welcome to the final part of an eight-part series on building loader applications in PHP. In this part, we’ll improve on the loader class we developed in the previous part by using certain specific functions from the Standard PHP Library (SPL).

Among the bunch of useful features that were incorporated into PHP 5 a long time ago, aside from the improved object model, there’s also a set of functions and classes that comprise what’s commonly called the Standard PHP Library (SPL).

As you may have heard, this library permits you to perform several clever tasks through a powerful API, such as working with predefined interfaces, traversing arrays and directories easily, loading classes automatically, and so forth. But it’s quite possible that at this point you may be wondering what the SPL has to do with building loader applications.

Well, I’m glad you asked, since some of the classes and functions that come packaged with the Standard PHP Library allow you to develop this kind of application in a much more compact and readable way, simplifying the code required for including specified resources and making it easier to create recursive methods.

In the preceding part of this series I explained how to create a loader program that could recursively search for a specified class through the file system on the web server.

While this sample application does its work pretty well when it comes to including classes in a transparent way, there’s plenty of room to improve its recursive loading method. And here’s where the SPL comes in, since it’s possible to use a combination of its “spl_autoload_register()” function and its RecursiveDirectoryIterator class to refactor the method in question and make it shorter and tightrer.

So, with that goal in mind, in this final chapter of the series I’m going to improve the loader class developed in the previous one by incorporating some of the aforementioned SPL functions and classes.

Are you ready to discover the power of using directory iterators for building a more efficient class loading program in PHP 5? Then, don’t waste more time in preliminaries; start reading right now!

{mospagebreak title=Review: the previous class loader program}

It’s possible that you still haven’t had an opportunity to look at the penultimate article of this series, where I discussed the development of a class loader program that could recursively seek a specified class through the file system on the web server, starting from a supplied path.

Thus, taking this possibility into account, below I listed the entire source code of this sample application, along with an example that shows how to use it in a concrete case.

First, here’s the signature of the class that composes the loader program:

// register autoload() method of Autoloader class

 

spl_autoload_register(‘Autoloader::autoload’);

 

// define Autoloader class

class Autoloader

{

public function __construct(){}

 

// autoload specified file

public static function autoload($file)

{

// the path should be defined as a constant or similar

$path = $_SERVER['DOCUMENT_ROOT'] . ‘/loader_classes/’;

$filepath = $_SERVER['DOCUMENT_ROOT'] . ‘/loader_classes/’ . $file . ‘.php’;

if (file_exists($filepath))

{

require_once($filepath);

}

else

{

Autoloader::recursive_autoload($file, $path);

}

}

 

// try to load recursively the specified file

public static function recursive_autoload($file, $path)

{

if (FALSE !== ($handle = opendir($path)))

{

// search recursively the specified file

while (FAlSE !== ($dir = readdir($handle)))

{

if (strpos($dir, ‘.’) === FALSE)

{

$path .= ‘/’ . $dir;

$filepath = $path . ‘/’ . $file . ‘.php’;

if (file_exists($filepath))

{

require_once($filepath);

break;

}

Autoloader::recursive_autoload($file, $path);

}

}

closedir($handle);

}

}

}

With the definition of the above “Autoloader” class available, it’s time to create another one, called “User,” which will be used for testing purposes. Here’s how it looks:

class User

{

 private $name = ‘Alejandro’;

private $email = ‘alejandro@domain.com’;

 

// constructor

public function __construct($name = ”, $email = ”)

{

if ($name != ”)

{

$this->name = $name;

 

}

if ($email != ”)

{

$this->email = $email;

}

}

 

// get user name

public function get_name()

{

return $this->name;

}

 

// get user’s email address

public function get_email()

{

return $this->email;

}

 

function __toString()

{

return ‘Name: ‘ . $this->name . ‘ Email: ‘ . $this->email;

}

}

Nothing unexpected, right? The definition of the previous “User” class is so simple to understand that it doesn’t bear any further explanation. So, it’s time to see how the “Autoloader” class can be used for creating a new user object and displaying some user-related data.

Here’s the short script that performs this task in four lines of code:

// create instance of User class

$user = new User();

// display user data

echo $user;

There you have it. As long as the “User” class is located at the specified web server’s directory or below, the “Autoloader” class will seek it recursively and include it in the calling script.

So far, everything looks good. However, as I expressed in the introduction, it’s possible to improve the implementation of its “autoload()" method by using the directory iterator class that comes bundled with the Standard PHP Library, which permits you to traverse folders and subfolders in a true painless fashion.

Therefore, assuming that you’re interested in learning how to use a directory iterator to make the previous “Autoloader” class more efficient, in the section to come I’m going to refactor the ”autoload()” method by using this native PHP 5 class.

Now, click on the link below and keep reading.

{mospagebreak title=Improving the definition of the Autoloader class using directory iterators} 

As you’ll possibly recall, the “autoload()” method that belongs to the previous loader class performs the recursive search of a particular class via another method, not surprisingly called “recursive_autoload().” As I mentioned earlier, though, it’s feasible to simplify this process by means of the RecursiveDirectoryIterator class that comes with the SPL library.

To demonstrate how this can be accomplished, below I included an improved version of the “Autoloader” class, this time using the directory iterator class. Here’s how the class now looks:

spl_autoload_register(NULL, FALSE);

spl_autoload_extensions(‘.php’);

spl_autoload_register(array(‘Autoloader’, ‘autoload’));

 

// define Autoloader class

class Autoloader

{

// constructor not implemented

public function __construct(){}

 

// autoload recursively a specified class

public static function autoload($class)

{

// Set path for specified file

$class = strtolower($class) . ‘.php’;

// try to include recursively the class file

$rit = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(BASEPATH));

foreach ($rit as $entry)

{

if ($class === $entry->getFileName())

{

require_once($entry->getPathname());

return;

}

}

throw new FileNotFoundException(‘File ‘ . $class . ‘ not found!’);

}

}

 

// define custom FileNotFoundException exception class

class FileNotFoundException extends Exception

{

public function __construct($message)

{

parent:: __construct();

die($message);

}

}

Definitely, things are getting much more interesting now. As you can see, the “autoload()” method defined above uses the functionality of the RecursiveDirectoryIterator native class to recursively search for a specified class through the file system. If the class in question is found, then it’s included via a simple “require_once()” function. Otherwise, a custom “FileNotFoundException” exception is thrown and caught appropriately. Not too difficult to grasp, right?

From the code sample shown previously, it’s obvious to see how useful the Standard PHP library can be for loading classes automatically and performing recursive searches.

However, the best way to understand how the enhanced version of the “Autoloader” class works is by means of an illustrative example. Therefore, in the last section of this article, I’m going to develop that example, in this case for loading the “User” class defined before.

Now, jump forward and read the next few lines. We’re almost done!

{mospagebreak title=Putting the Autoloader class into action} 

As you may have noticed when I showed the improved signature of the “Autoloader” class, it used a constant called BASEPATH to start looking for a specified class. But in this particular case, this constant will be defined outside the class, instead of storing its value as a property.

Naturally, you can change this condition and take the approach that best fits your needs and requirements. So, having clarified that point, let me show you a simple script that demonstrates how to  dynamically include the previous “User” class.

The code required to perform this task is as simple as this:

// define base path to search for specified class

define(‘BASEPATH‘, $_SERVER['DOCUMENT_ROOT'] . ‘/loader_classes/’);

// create instance of User class (it’s autoloaded by the Autoloader class)

$user = new User();

// display user data

echo $user; 

In reality, apart from creating an instance of the sample “User” class and displaying some data on it, the above script only defines the corresponding BASEPATH constant and nothing else, since the inclusion of the class is handled behind scenes via the autoloading application.

Even though this concrete example only shows how to include a trivial class, it still illustrates in a nutshell how to build efficient loader programs in PHP 5 that take advantage of the functionality provided by the Standard PHP Library.

From this point onward, feel free to edit all of the code samples developed in this tutorial to help you get started developing your own file loading programs. 

Final thoughts  

It’s hard to believe, but we’ve come to the end of this series. I hope the experience has been educational, since through all the tutorials you learned how to build different kinds of file loader programs with PHP 5.

Ranging from explicitly using PHP includes to working with some of the functions and classes available in the Standard PHP Library, the variety of applications that load classes transparently is pretty huge. But, since the logic implemented by those programs is very similar, you shouldn’t have major problems adding them to your toolbox.

See you in the next PHP development tutorial!

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan