I'm learning to use php autuoloader
...
As much as I understand, we can use __autoloader
or spl_autoloader_*
to auto load files.
Assume this is my directories structure :
ROOT
|
|
ADMIN
| |
| |
| DIST
| |
| SOME_FOLDER
| SOME_FOLDER
| TPL
| |
| |
| SOME_FOLDER1
| |
| test.php
| SOME_FOLDER2
| |
| example1.php
| example2.php
| example3.php
|
|
CLASSES
|
basics.php
class1.php
class2.php
class3.php
class4.php
|
index.php
I made this class for autoload files in CLASSES
directory :
basics.php :
class MyAutoLoader
{
public function __construct()
{
spl_autoload_register( array($this, 'load') );
}
function load( $file )
{
//spl_autoload( 'load1' );
echo 'Try to call ' . $file . '.php inside ' . __METHOD__ . '<br>';
require( $file . '.php' );
}
}
and in index.php
I will include basics.php
and every thing is fine for files are stored in CLASSES
folder...
require_once("CLASSES/basics.php");
$loaderObject = new MyAutoLoader();
with this code, I can declare class1
...
class3
Now I want to have an autoloder that could be load files in SOME_FOLDER2
which in this case are example1.php
, example2.php
and example3.php
I tried some cases but the files in SOME_FOLDER2
won't be load using autoloader.
My attempts :
I made a function named load2
in MyAutoLoader
class that try to include files from SOME_FOLDER2
function load2( $file )
{
//spl_autoload_register('load2');
echo 'Inside LOADER2 ' . __METHOD__ . '<br>';
require ( 'ADMIN/TPL/' . $file . '.php' );
}
And I changed spl_autoload_register
in MyAutoLoader
constructor :
$allMethods = get_class_methods( 'MyAutoLoader' );
$allMethods = array_splice( $allMethods, 1 );
foreach( $allMethods as $method )
{
spl_autoload_register( array($this, $method) );
}
But none of them didn't work for me...
Would you please tell me what's wrong in my code or what is my misunderstanding about auloader?
Thanks in Advance
I think your problem basically boils down to not checking if the file exists before require
ing it... that will produce a fatal error if the file doesn't exist in the first folder that you attempt to include from.
I don't know your use case, but here are some suggestions:
Can you just use a single autoloader?
function my_autoload($class_name) {
if (is_file('CLASSES/' . $class_name . '.php')) {
require_once 'CLASSES/' . $class_name . '.php';
} else if (is_file('ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php')) {
require_once 'ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php';
}
}
spl_autoload_register("my_autoload");
Or if you need to declare them independently (ie. two or more autoloaders):
function classes_autoload($class_name) {
if (is_file('CLASSES/' . $class_name . '.php')) {
require_once 'CLASSES/' . $class_name . '.php';
}
}
spl_autoload_register("classes_autoload");
function admin_autoload($class_name) {
if (is_file('ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php')) {
require_once 'ADMIN/TPL/SOME_FOLDER2/' . $class_name . '.php';
}
}
spl_autoload_register("admin_autoload");
Or make your autoloader class generic:
class MyAutoLoader {
private $path;
public function __construct($path) {
$this->path = $path;
spl_autoload_register( array($this, 'load') );
}
function load( $file ) {
if (is_file($this->path . '/' . $file . '.php')) {
require_once( $this->path . '/' . $file . '.php' );
}
}
}
$autoloader_classes = new MyAutoLoader('CLASSES');
$autoloader_admin = new MyAutoLoader('ADMIN/TPL/SOME_FOLDER2');
If you don't want to manually keep the list of child folders inside ADMIN/TPL
up to date you could even do something like this to autoload from any of them (this obviously assumes that all subfolders of ADMIN/TPL
contains classes):
function my_autoload($class_name) {
if (is_file('CLASSES/' . $class_name . '.php')) {
require_once 'CLASSES/' . $class_name . '.php';
} else {
$matching_files = glob('ADMIN/TPL/*/' . $class_name . '.php');
if (count($matching_files) === 1) {
require_once $matching_files[0];
} else if (count($matching_files) === 0) {
trigger_error('Could not find class ' . $class_name . '!', E_USER_ERROR);
} else {
trigger_error('More than one possible match found for class ' . $class_name . '!', E_USER_ERROR);
}
}
}
spl_autoload_register("my_autoload");