Sorry about the vague title, but I am trying to find some better alternatives to having to call an Autoloader
class, and the register
method multiple times, to map class paths as seen below.
$ClassLoader = new Autoloader\Loader(__DIR__.'/path/to/someclass');
$ClassLoader->register();
$ClassLoader = new Autoloader\Loader(_DIR__.'/path/to/anotherclass');
$ClassLoader->register();
$ClassLoader = new Autoloader\Loader(__DIR__.'/path/to/anotherclass');
$ClassLoader->register();
$ClassLoader = new Autoloader\Loader(__DIR__.'/path/to/anotherclass');
$ClassLoader->register();
$ClassLoader = new Autoloader\Loader(__DIR__.'/path/to/anotherclass');
$ClassLoader->register();
This goes on and on for about 50 lines, and I would like to know how I can handle the autoloading classes with simple few lines solution. I can obviously inject an array, to the constructor:
$ClassLoader = new Autoloader\Loader( ['paths'=>[
'/path/to/class/',
'/path/to/anotherclass',
'/path/to/anotherclass'
]);
$ClassLoader->register();
But, I am not sure if this method is recommended at-least from OOP good practice point of view.
Perhaps this is what you are looking for.
For each directory that contains your classes run ::add
.
namespace ClassLoader;
class Loader
{
protected $directories = array();
public function __construct()
{
spl_autoload_register([$this, 'load']);
}
public function add($dir)
{
$this->directories[] = rtrim($dir, '/\\');
}
private function load($class)
{
$classPath = sprintf('%s.php', str_replace('\\', '/', $class));
foreach($this->directories as $dir) {
$includePath = sprintf('%s/%s', $dir, $classPath);
if(file_exists($includePath)) {
require_once $includePath;
break;
}
}
}
}
$loader = new Loader();
$loader->add(__DIR__.'/src');
$loader->add(__DIR__.'/vendor');
use Symfony\Component\Finder\Finder;
$finder = new Finder();
// Included /var/www/test/vendor/Symfony/Component/Finder/Finder.php
// I put the Symfony components in that directory manually for this example.
print_r($finder);
It is effectively the same as with composer though, just less adaptive or performant.
For this you can use Composer: https://getcomposer.org/download/
You will get a file called composer.phar
.
Place this in your project directory, then go to that directory on your command line.
Run php composer.phar init
.
This will ask you a few questions which you can ignore, in the end you get a new file called composer.json
It should look something like this:
{
"autoload": {
"psr-0": { "": "src/" }
},
"require": {}
}
Add the autoload
field, and replace src/
with the directory containing your classes.
Make sure that directory exists.
Then run php composer.phar install
.
This will create a directory called vendor
. Inside this directory is a file called autoload.php
.
Include this file in the bootstrap of your project, and all classes within your source directory will automatically be loaded in.
Have you looked into spl_autoload_register function?
usage
// pre php 5.3
function my_autoloader($class) {
include 'classes/' . $class . '.class.php';
}
spl_autoload_register('my_autoloader');
// Or, using an anonymous function as of PHP 5.3.0
spl_autoload_register(function ($class) {
include 'classes/' . $class . '.class.php';
});
then place all your classes in "classes" folder and when you initialise them with the new
keyword, they will be auto-included. Works with static classes also.
for example:
$myClassOb1 = new MyClass();
// will include this file: classes/MyClass.class.php
or
$email = Utils::formatEmail($emailInput);
// will include this file: classes/Utils.class.php