0

Here is a partial structure of my project

root  
  |-App
     |--Controller
          |--Common
               |-HomeController.php
               |-HeaderController.php
               |-FooterController.php
               |-SidebarController.php
           |--Info
               |-AboutController.php
               |-ContactController.php

I have my controllers placed in their corresponding directories for better management.

I recently added namespaces to them.

HomeController.php = namespace app\controller\common; 
HeaderController.php = namespace app\controller\common;

AboutController.php = namespace app\controller\info; 
ContactController.php = namespace app\controller\info;

To load these controllers, I am checking this autoloader below

spl_autoload_register(function ($class) {

    $prefix = 'app\controller\common\\';
    $base_dir = __DIR__ . '/app/controller/common/'; // your classes folder

    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) {
        return;
    }
    $relative_class = substr($class, $len);
    $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
    if (file_exists($file)) {
        require $file;
    }
});

$home = new app\controller\common\HomeController();
$home->index();

and it works i.e. it autoload all controllers in the folder app > controller > common.

The problem is I do not understand how to load all other controllers which are in different folders (like the ones in the Info folder) and with different sub-namespace (namespace app\controller\info, namespace app\controller\client)?

The autoload has the namespace prefixed defined to $prefix = 'app\controller\common\\'; and I guess this is what I need to fix to accommodate all other controllers that there is to load them.

How do I fix this $prefix?

Mecom
  • 381
  • 3
  • 20
  • 1
    Honestly, I'd suggest just using [Composer](https://getcomposer.org/). It comes with what you need and more, it works on any platform, it's easy to understand and very portable. – Andrei Nov 14 '17 at 08:42

1 Answers1

1

You had the right idea there. But you went for anonymous functions, which in itself isn't necessarily wrong it just doesn't fit the your current case problem very well. You're better of with regular functions.

You could do something like this:

spl_autoload_register('myAutoloader');

function myAutoloader($path) {
    foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path),\FilesystemIterator::SKIP_DOTS) as $file) {
        if ($file->getFileExtension() == 'php') {
            require $file->getFilename() . $file->getFileExtension();
        }
    }
}

This function will recursively iterate thru a folder and require any php file it finds. What it won't do is take care of various dependencies, so keep that in mind.

spl_autoload_register() allows you to register multiple functions (or static methods from your own Autoload class) that PHP will put into a stack/queue and call sequentially when a "new Class" is declared.

Quote is from this question, which I strongly recommend you read.


With that said, I encourage you to use Composer. It was designed specifically for your exact problem. You can load anything with it. Not just php files.

Andrei
  • 3,434
  • 5
  • 21
  • 44