My blog has moved to http://blog.derekbobo.com

I moved my blog. Visit http://blog.derekbobo.com for the new one!

Recursively autoload classes in PHP

Posted by derekbobo on February 17, 2009

For those of you who are not aware of PHP’s autoload function, you can read about it here. Basically it allows you to do some lazy loading of classes. Instead of having to manually include files, you can just instantiate classes on the fly. If the object name is not in scope it will call the autoload function to attempt to load it.

For example:

include_once “common/classes/myclass.php”;
$objMyClass = new MyClass();

With an autoload function defined this can now be coded by simply doing this:

$objMyClass = new MyClass();

This is particularly helpful with large projects as it helps keep your code lean. You can read the basic examples from the manual, but I wanted to share a way to recursively autoload files. Here is my Autoload.php file which simply needs to be included by any page you wish to leverage autoloading on. In my framework I only need to include it once, basically in my index.php file.

  • The constants are first defined in a Config.php file.
  • All files in the HELPER_DIR are included as these are general functions that are leveraged in classes or inline.
  • After including helper files this would essentially start at the next defined root directory and then look through all files and folders while attempting to include the appropriate class. (LIBRARY_DIR then ADDON_DIR then CONTROLLER_DIR then MODEL_DIR then VIEW_DIR then EXTENSION DIR).
  • File names should be the same as the object name, minus the .php extension. For example if your class name was MyClass it should live in a file called MyClass.php.

I’m not suggesting that this is an optimal solution. In fact, the way I’m determing if the include file was found is a bit of a hack, but it does work and demonstrates a handy function of PHP. If there are any questions on this implementation don’t hesitate to ask.

<?php

doFindAndInclude(HELPER_DIR, "", true);

function __autoload($strClass)
{
   $blnDone = false;
   if( !$blnDone )
   {
      $blnDone = doFindAndInclude(LIBRARY_DIR, $strClass, false);
   }

   if( !$blnDone )
   {
      $blnDone = doFindAndInclude(ADDON_DIR, $strClass, false);
   }

   if( !$blnDone )
   {
      $blnDone = doFindAndInclude(CONTROLLER_DIR, $strClass, false);
   }

   if( !$blnDone )
   {
      $blnDone = doFindAndInclude(MODEL_DIR, $strClass, false);
   }

   if( !$blnDone )
   {
      $blnDone = doFindAndInclude(VIEW_DIR, $strClass, false);
   }

   if( !$blnDone )
   {
      $blnDone = doFindAndInclude(EXTENSION_DIR, $strClass, false);
   }
}

function doFindAndInclude($strDirectory, $strFilename, $blnIncludeAll)
{
   ob_start();
   doRecursiveFindAndInclude($strDirectory, $strFilename, $blnIncludeAll);
   $included = ob_get_contents();
   ob_end_clean();
   return $included != "";
}

function doRecursiveFindAndInclude($strDirectory, $strFilename, $blnIncludeAll)
{
   if( $handle = opendir($strDirectory) )
   {
      while( false !== ($file = readdir($handle)) )
      {
         if( $file != "." && $file != ".." )
         {
            if(is_dir($strDirectory . "/" . $file))
            {
               doRecursiveFindAndInclude($strDirectory . $file . "/", $strFilename, $blnIncludeAll);
			}
			else
			{
			   $strCurrent = $strDirectory . $file;
			   $strTestFilename = $strDirectory . $strFilename . ".php";

			   $pathinfo = pathinfo($strCurrent);
			   $extension = $pathinfo['extension'];

			   if( $strCurrent == $strTestFilename && !$blnIncludeAll )
			   {
			   	  include_once $strCurrent;
			      echo "FOUND: " . $strCurrent;
			   }
			   else if( $blnIncludeAll && $extension == "php" ) //Don't include directories
			   {
			      include_once $strCurrent;
			      echo "INCLUDE: " . $strCurrent;
			   }
			}
		 }
	  }
      closedir($handle);
   }
}

?>
Advertisements

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 )

Google photo

You are commenting using your Google 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

 
%d bloggers like this: