views:

31

answers:

2

PHP 5.3.3-pl1-gentoo (cli) (built: Aug 17 2010 18:37:41)

Hi all, I use a simple autoloader in my project's main file (index.php):

require_once("./config.php");
require_once("./app.php");
require_once("./../shared/SqlTool.php");

function __autoload($className) {
    $fn = 'file-not-exists-for-{$className}';
    if (file_exists("./specific/php/{$className}.php")) { $fn = "./specific/php/{$className}.php"; } else
     { $fn = "./../shared/{$className}.php";}
    require_once($fn);
}

$sql = new SqlHD(); // class SqlHD, in ./specific/php/SqlHD.php extends SqlTool
$web = new HTMLForm($sql); // class HTMLForm in HTMLForm.php
$app = new App($sql, $web); // class App in App.php
$app->Main();

The problem: without that require_once("./../shared/SqlTool.php");, script can't execute SqlHD.php, because it can't find SqlTool.php by itself, and for some reason it doesn't uses autoload routine defined in main file.

I tried this:

spl_autoload_register(__NAMESPACE__ .'\Test::load');

class Test {
    static public function load($className){
        $fn = 'file-not-exists-for-{$className}';
        if (file_exists("./specific/php/{$className}.php")) { $fn = "./specific/php/{$className}.php"; } else
         { $fn = "./../shared/{$className}.php}";}
        echo realpath($fn);//"$curRealDir Filename $fn\n";
        echo "\n";
        require_once($fn);
    }   
}

Well,

PHP Warning: require_once(./../shared/SqlTool.php}): failed to open stream: No such file or directory in /home/beep/work/php/hauthd/index.php on line 20 PHP Fatal error: require_once(): Failed opening required './../shared/SqlTool.php}' (include_path='.:/usr/share/php5:/usr/share/php') in /home/beep/work/php/hauthd/index.php on line 20

So it doesn't reacts to any request from extended class.

Last second idea: put spl_autoload_register to each file. But cannot put it to "extends" directive itself!

P.S. May rewrite SqlTool.php using Factory pattern so it would automatically return an instance of project-specifc class, but it seems to be not a best way, or it is..?

+2  A: 

If SqlHD extends SqlTool, then your __autoload() function should include this automatically.

Note you have an extra '}' in your filename which is probably messing this up. (Which you have also copy 'n' pasted into your 2nd code snippet.)

{ $fn = "./../shared/{$className}.php}";}

As an aside, I think you only need to require() inside your __autoload() function, rather than require_once(), since your __autoload() function is only called if it has not already been loaded.

w3d
+1  A: 

[Edit: removed incorrect relative path suggestion - w3d spotted the real problem. Leaving the rest here just for info]

Also you can change the require_once in the autoload function to just require - by definition the function will only run if the class has not already been included.

You could greatly simplify your autoload by utilising the include path, as then PHP would check the different locations for you. E.g. something like this:

set_include_path(
    realpath('./specific/php') . PATH_SEPARATOR .
    realpath('./../shared') . PATH_SEPARATOR .
    get_include_path()
);

function __autoload($className) {
    require "$className.php";
}
Tim Fountain