PHP Classes

File: Autoloader.php

Recommend this page to a friend!
  Classes of Andrei Alexandru   Enhanced PSR 4 Autoloader   Autoloader.php   Download  
File: Autoloader.php
Role: Class source
Content type: text/plain
Description: Main class
Class: Enhanced PSR 4 Autoloader
Autoloader that supports PSR 4 with enhancements
Author: By
Last change:
Date: 8 years ago
Size: 5,364 bytes
 

Contents

Class file image Download
<?php
/**
 *
 * @author Andrei Alexandru Romila
 * @version 1.0
 *
 */
class Autoloader {
   
   
/**
     * PHP default file extension
     *
     * @var string
     */
   
const PHP_EXTENSION = '.php';

   
/**
     * Stores all namespaces and directories
     *
     * @var array
     */
   
protected $prefixes = array();
   
   
/**
     * Stores all the files
     *
     * @var array
     */
   
protected $files = array();

   
/**
     *
     * @param boolean $register
     */
   
public function __construct($register = false) {
        if (
$register === true) {
           
$this->registerAutoloader();
        }
    }

   
/**
     * Registers a new autoloader funtion
     *
     * @return boolean Returns true on success or false on failure.
     */
   
public function registerAutoloader() {
        return
spl_autoload_register(array($this, 'loadClass'), false, true);
    }
   
   
/**
     * Register a new file for a classname.
     *
     * @param string $class The name of the class
     * @param string $filename The filename
     * @param boolean $replace If the class is already register, replace the filename
     */
   
public function registerFile($class, $filename, $overwrite = false) {
       
        if (
is_file($filename) === false || is_readable($filename) === false) {
            echo
'The file: ' . $filename . ' doen\'t exist or is not readable!<br />';
            return;
        }
       
       
// Remove the '\' if the class is \ClassName
       
$class = rtrim($class, '\\');
       
       
// Get real path of the file and normalize directory separator
       
$filename = realpath($filename);
       
$filename = str_replace('\\', '/', $filename);
       
       
// If is not set yet, create it
       
if (isset($this->files[$class]) === false) {
           
           
$this->files[$class] = $filename;
           
        } else if (
$overwrite === true) {
           
           
// Overwrite the last filename
           
$this->files[$class] = $filename;
           
        }
    }

   
/**
     * Registers a new namespace in the loader
     *
     * @param string $namespace The namespace
     * @param string $directory Path to the namespace
     */
   
public function registerNamespace($namespace, $directory, $prepend = false) {
   
        if (
is_dir($directory) === false || is_readable($directory) === false) {
            echo
'The directory: ' . $directory . ' doen\'t exist or is not readable!<br />';
            return;
        }
       
       
$namespace = trim($namespace, '\\') . '\\';
       
$directory = realpath($directory);
       
$directory = str_replace('\\', '/', $directory) . '/';
   
       
// If doesnt exist create a new array for the namespace.
       
if (false === isset($this->prefixes[$namespace])) {
           
           
$this->prefixes[$namespace] = array();
           
        } else if (
in_array($directory, $this->prefixes[$namespace], true)) {
           
           
// Already added ...
           
return;
       
        }
   
        if (
$prepend === true) {
           
// Prepend this namespace
           
$this->prefixes[$namespace] = array_unshift($this->prefixes[$namespace], $directory);
        } else {
           
// A bit faster than array_push($array, $value1)
           
$this->prefixes[$namespace][] = $directory;
        }
       
    }
   
   
/**
     * PSR4 loadClass function with some enhancements.
     *
     * @param string $class
     */
   
public function loadClass($class) {
       
       
// Check for direct file registration - a bit faster than searching in a sub folder
       
if (isset($this->files[$class]) && $this->requireFile($this->files[$class])) {
            return
$this->files[$class];
        }
       
       
// the current namespace prefix
       
$prefix = $class;
       
       
// work backwards through the namespace names of the fully-qualified
        // class name to find a mapped file name
       
while (false !== ($position = strrpos($prefix, '\\'))) {
       
           
// retain the trailing namespace separator in the prefix
           
$prefix = substr($class, 0, $position + 1);
       
           
// the rest is the relative class name
           
$relative = substr($class, $position + 1);
       
           
// try to load a mapped file for the prefix and relative class
           
$filename = $this->loadFile($prefix, $relative);
            if (
$filename) {
                return
$filename;
            }
       
           
// remove the trailing namespace separator for the next iteration
            // of strrpos()
           
$prefix = rtrim($prefix, '\\');
        }
       
       
// never found a mapped file
       
return false;
       
    }
   
   
/**
     * Load the mapped file for a namespace prefix and relative class.
     *
     * @param string $prefix The namespace prefix.
     * @param string $relativePath The relative class name.
     * @return mixed Boolean false if no mapped file can be loaded, or the
     * name of the mapped file that was loaded.
     */
   
protected function loadFile($prefix, $relativePath) {
       
       
// are there any base directories for this namespace prefix?
       
if (isset($this->prefixes[$prefix]) === false) {
            return
false;
        }
   
       
// look through base directories for this namespace prefix
       
foreach ($this->prefixes[$prefix] as $directory) {
           
           
$filename = $directory . str_replace('\\', '/', $relativePath) . self::PHP_EXTENSION;
   
           
// if the mapped file exists, require it
           
if ($this->requireFile($filename)) {
                return
$filename;
            }
        }
   
       
// never found it
       
return false;
    }
   
   
/**
     * If a file exists, require it from the file system.
     *
     * @param string $file The file to require.
     * @return bool True if the file exists, false if not.
     */
   
protected function requireFile($filename) {
       
        if (
is_readable($filename)) {
            require
$filename;
            return
true;
        }
       
        return
false;
    }
   
}