Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I load classes from multiple directories with __autoload?

Following up on this question, it seems that the duplicate issue could be solved by just using the __autoload code below,

function __autoload($class_name) 
{
    include AP_SITE."classes_1/class_".$class_name.".php";
}

$connection = new database_pdo(DSN,DB_USER,DB_PASS);
var_dump($connection);

result,

object(database_pdo)[1]
  protected 'connection' => 
    object(PDO)[2]

but this only loads the classes from one directory, what about other directories? Because I group the classes in different directories. So I will get error if I want to load classes from other directories,

function __autoload($class_name) 
{
    include AP_SITE."classes_1/class_".$class_name.".php";
    include AP_SITE."classes_2/class_".$class_name.".php";
}

message,

Warning: include(C:/wamp/www/art_on_your_doorstep_2011_MVC/global/applications/CART/classes_2/class_database_pdo.php) [function.include]: failed to open stream: No such file or directory in ...

which refers to this line - include AP_SITE."classes_2/class_".$class_name.".php";

So, my question is - how can I load classes from multiple directories with __autoload?

a possible solution:

function autoload_class_multiple_directory($class_name) 
{

    # List all the class directories in the array.
    $array_paths = array(
        'classes_1/', 
        'classes_2/'
    );

    # Count the total item in the array.
    $total_paths = count($array_paths);

    # Set the class file name.
    $file_name = 'class_'.strtolower($class_name).'.php';

    # Loop the array.
    for ($i = 0; $i < $total_paths; $i++) 
    {
        if(file_exists(AP_SITE.$array_paths[$i].$file_name)) 
        {
            include_once AP_SITE.$array_paths[$i].$file_name;
        } 
    }
}

spl_autoload_register('autoload_class_multiple_directory');
like image 559
Run Avatar asked Oct 16 '25 14:10

Run


1 Answers

You can register multiple autoload functions by using spl_autoload_register instead of the single __autoload function. That's the recommended way.

If one autoloader was able to load the file, the next one in the stack won't be called.

Each autoloader however should only load the classes it is for, so you need to check that by the classname and/or with is_file. By classname often is better because trying wildly on the file-system can stress a system if your application grows.

To not re-invent the wheel, you could even use an autoloader that already exists which is able to deal with the PSR-0 standard on file-name-calling. Those often allow to register a specific namespace on a base-directory. In your case that would mean that you must rename and organize your files according to the PSR-0 convention.


The quick solution (bound to your question):

function __autoload($class_name) 
{
    $file = sprintf('%sclasses_1/class_%s.php', AP_SITE, $class_name);
    if (is_file($file))
    {
        include $file;
        return;
    }
    $file = sprintf('%sclasses_2/class_%s.php', AP_SITE, $class_name);
    if (is_file($file))
    {
        include $file;
        return;
    }
}

As you can see, there is already code duplicated (as in yours). So this should just be a temporary solution as you will end up with more and more duplicated lines for each directory you would like to test for. If you consider to change the design, please take the PSR-0 shema into account, it helps to streamline one's codebase and makes it easy to re-use other existing compontents in the PHP world.


function autoload_class_multiple_directory($class_name) 
{

    # List all the class directories in the array.
    $array_paths = array(
        'classes_1/', 
        'classes_2/'
    );

    foreach($array_paths as $path)
    {
        $file = sprintf('%s%s/class_%s.php', AP_SITE, $path, $class_name);
        if(is_file($file)) 
        {
            include_once $file;
        } 

    }
}

spl_autoload_register('autoload_class_multiple_directory');
like image 78
hakre Avatar answered Oct 18 '25 14:10

hakre



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!