Advertisement
Guest User

AutoLoader

a guest
Jun 19th, 2014
1,158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.50 KB | None | 0 0
  1. <?php
  2.  
  3. namespace Toolbox\Testing;
  4.  
  5. /**
  6.  * This class is an auto loader for use with vanilla PHP projects' testing environment. Use it in
  7.  * the bootstrap to register classes without having to use a framework (which you can, and should if
  8.  * it's a better solution for you) and without having to use includes everywhere.
  9.  *
  10.  * It assumes that the file path in relation to the namespace follows the PSR-0 standard.
  11.  *
  12.  * IMPORTANT NOTE: When just registering directories, the class has no ability to discern
  13.  * conflicting class names in different namespaces, which means that classes with the same name will
  14.  * override each other! Always use the registerNamespace()-method if possible!
  15.  *
  16.  * Inspired by Jess Telford's AutoLoader (http://jes.st/).
  17.  *
  18.  * @see http://jes.st/2011/phpunit-bootstrap-and-autoloading-classes/
  19.  * @see http://petermoulding.com/php/psr
  20.  * @see http://www.php-fig.org/psr/psr-0/
  21.  *
  22.  * @codeCoverageIgnore
  23.  *
  24.  * @category    Toolbox
  25.  * @package     Testing
  26.  *
  27.  * @author      Helge Söderström <helge.soderstrom@schibsted.se>
  28.  */
  29.  
  30. class AutoLoader {
  31.    
  32.     /**
  33.      * An array keeping class names as key and their path as the value for classes registered with
  34.      * AutoLoader::registerNamespace().
  35.      *
  36.      * @var array
  37.      */
  38.     protected static $namespaceClassNames = array();
  39.  
  40.     /**
  41.      * An array keeping class names as key and their path as the value for classes registered with
  42.      * AutoLoader::registerDirectory().
  43.      *
  44.      * @var array
  45.      */
  46.     protected static $directoryClassNames = array();
  47.  
  48.  
  49.     /**
  50.      * Store the filename (sans extension) & full path to all ".php" files found for a namespace.
  51.      * The parameter should contain the root namespace as the key and the directory as a value.
  52.      *
  53.      * @param string $namespace
  54.      * @param string $dirName
  55.      * @return void
  56.      */
  57.     public static function registerNamespace($namespace, $dirName) {
  58.         $directoryContents = new \DirectoryIterator($dirName);
  59.         foreach($directoryContents as $file) {
  60.             if ($file->isDir() && !$file->isLink() && !$file->isDot()) {
  61.                 $newNamespace = $namespace . "_" . $file->getFileName();
  62.                 $newDirName = $dirName . "/" . $file->getFilename();
  63.                 static::registerNamespace($newNamespace, $newDirName);
  64.             } elseif (substr($file->getFilename(), -4) === '.php') {
  65.                 $className = substr($file->getFilename(), 0, -4);
  66.                 $namespacedClassName = $namespace . "_" . $className;
  67.                 $fileName = realpath($dirName) . "/" . $file->getFilename();
  68.                 static::$namespaceClassNames[$namespacedClassName] = $fileName;
  69.             }
  70.         }
  71.     }
  72.    
  73.    
  74.     /**
  75.      * Store the filename (sans extension) & full path of all ".php" files found.
  76.      *
  77.      * NOTE: This method will not be able to differentiate the same class names in different
  78.      *       namespaces and will therefore overwrite class names if multiple of the same name is
  79.      *       found. If possible, use registerNamespace instead!
  80.      *
  81.      * @param string $dirName
  82.      * @return void
  83.      */
  84.     public static function registerDirectory($dirName) {
  85.         $directoryContents = new \DirectoryIterator($dirName);
  86.         foreach ($directoryContents as $file) {
  87.             if ($file->isDir() && !$file->isLink() && !$file->isDot()) {
  88.                 // Recurse into directories other than a few special ones.
  89.                 static::registerDirectory($file->getPathname());
  90.             } elseif (substr($file->getFilename(), -4) === '.php') {
  91.                 // Save the class name / path of a .php file found.
  92.                 $className = substr($file->getFilename(), 0, -4);
  93.                 AutoLoader::registerClass($className, $file->getPathname());
  94.             }
  95.         }
  96.     }
  97.  
  98.  
  99.     /**
  100.      * Caches a found class with the class name as key and its path as value for use when loading
  101.      * on the fly. The class is registered with its class name only, no namespace.
  102.      *
  103.      * @param string $className
  104.      * @param string $fileName
  105.      * @return void
  106.      */
  107.     public static function registerClass($className, $fileName) {
  108.         AutoLoader::$directoryClassNames[$className] = $fileName;
  109.     }
  110.    
  111.  
  112.     /**
  113.      * Includes a found class in the runtime environment. Strips namespaces.
  114.      *
  115.      * @param string $className
  116.      * @return void
  117.      */
  118.     public static function loadClass($className) {
  119.         // First, see if we've registered the entire namespace.
  120.         $namespacedClassName = str_replace('\\', '_', $className);
  121.         if (isset(static::$namespaceClassNames[$namespacedClassName])) {
  122.             require_once(static::$namespaceClassNames[$namespacedClassName]);
  123.             return;
  124.         }
  125.        
  126.         // Nope. Have we registered it as a directory?
  127.         $psrDirectorySeparators = array('\\', '_');
  128.         foreach($psrDirectorySeparators as $separator) {
  129.             $separatorOccurrence = strrpos($className, $separator);
  130.             if($separatorOccurrence !== false) {
  131.                 $className = substr($className, $separatorOccurrence + 1);
  132.                 break;
  133.             }
  134.         }
  135.        
  136.         if (isset(AutoLoader::$directoryClassNames[$className])) {
  137.             require_once(AutoLoader::$directoryClassNames[$className]);
  138.         }
  139.     }
  140.  
  141. }
  142.  
  143. // Register our AutoLoad class as the system auto loader.
  144. spl_autoload_register(array('Toolbox\Testing\AutoLoader', 'loadClass'));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement