PHP Autoload with spl_autoload_register in a sub folder
-
06-06-2021 - |
Question
My directory structure is something like below
> Root
> -Admin // admin area
> --index.php // admin landing page, it includes ../config.php
> -classes // all classes
> ---template.php
> ---template_vars.php // this file is used inside template.php as $template_vars = new tamplate_vars();
> -templates // all templates in different folder
> --template1
> -index.php
> -config.php
in my config.php file i have used
<?php
.... // some other php code
spl_autoload_register(NULL, FALSE);
spl_autoload_extensions('.php');
spl_autoload_register();
classes\template::setTemplate('template/template1');
classes\template::setMaster('master');
.... // some other php code
?>
I have set the proper namespaces (only in classes) and in my index.php on root I access the classes
<?php
require 'config.php';
$news_array = array('news1', 'news1'); // coming from database
$indexTemplate = new \classes\template('index');
$indexTemplate->news_list = $news_array; // news_list variable inside index template is magically created and is the object of template_vars class
$indexTemplate->render();
?>
So far it is working perfect, it renders the template and populate the template vars,
but when I open index file in admin folder, it gives following error
Fatal error: Class 'classes\template_vars' not found in /home/aamir/www/CMS/classes/template.php on line 47
any idea how to fix this thing. It works on root, but from inside admin panel it doesnot work
Solution
You have to use a trick for that:
set_include_path(get_include_path() . PATH_SEPARATOR . '../');
Before you include ../config.php
OR
set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ . '/');
Inside config.php
OTHER TIPS
I faced the same problem (on windows) and i think i can explain the matter.
For instance let's take two simple scripts, the first one creates a class in a namespace
called root
in a dir called root
:
-root\sampleClass.php
:
namespace root;
class sampleClass
{
public function __construct()
{
echo __CLASS__;
}
public function getNameSpace()
{
return __NAMESPACE__;
}
}
and the second script located here root\index.php
and contains only those two lines :
spl_autoload_register();
$o = new sampleClass;
then if you run the root\index.php
script you will get a FATAL error like this:
( ! ) SCREAM: Error suppression ignored for
( ! ) Fatal error: spl_autoload(): Class sampleClass could not be loaded in C:\wamp\www\root\test.php on line 4
And if you remove the namespace keyword on the root\sampleClass.php
, the error vanish.
So I won't conclude anything about the demeanor of the core php because i am not a php core dev but something like this happen:
If you don't specify a namespace the spl_autoload_register();
function will also look in the current dir (which is root\
) and find the class called sampleClass.php
but if you specify a namespace like root
in our example the spl_autoload_register();
function will try to load a file located somewhere like "root\root".
So at this point you have two solutions :
1) first which is not proper is to create a subdir called root
which also contains the sampleClass.php
2) second which is better is to add a kind of trick in the index.php
script :
set_include_path(get_include_path().PATH_SEPARATOR.realpath('..'));
which will tell the spl_autoload_register()
function to check in the parent dir.
That's all