PHP глобальное, вложенное / унаследованное автозагрузка - PullRequest
1 голос
/ 11 октября 2010

PHP 5.3.3-pl1-gentoo (cli) (построен: 17 августа 2010 18:37:41)

Привет всем, я использую простой автозагрузчик в главном проекте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();

Проблема: без этого require_once("./../shared/SqlTool.php"); скрипт не может выполнить SqlHD.php, потому что он не может найти SqlTool.php сам по себе и по какой-то причинеон не использует процедуру автозагрузки, определенную в главном файле.

Я пробовал это:

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);
    }   
}

Ну,

PHP Предупреждение: require_once (./../shared/SqlTool.php}): не удалось открыть поток: нет такого файла или каталога в /home/beep/work/php/hauthd/index.php в строке 20 PHP Неустранимая ошибка: require_once (): не удалось открыть обязательно './../shared/SqlTool.php} '(include_path ='.: / usr / share / php5: / usr / share / php ') в /home/beep/work/php/hauthd/index.php on line20

Так что он не реагирует ни на один запрос от расширенного класса.

Последняя вторая идея: поместите spl_autoload_register в каждый файл.Но он не может поместить его в директиву "extends"!

PS Может переписать SqlTool.php, используя шаблон Factory, чтобы он автоматически возвращал экземпляр класса, специфичного для проекта, но, похоже, это не лучшийКстати, или это ..?

Ответы [ 2 ]

2 голосов
/ 11 октября 2010

Если SqlHD расширяет SqlTool, то ваша функция __autoload () должна включать это автоматически .

Обратите внимание, у вас есть лишний '}' в вашем имени файла, который, вероятно, испортил это.(Который вы также скопировали и вставили в ваш второй фрагмент кода 'n'.)

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

В качестве отступления, я думаю, вам нужно всего лишь require() внутри функции __autoload (), а не require_once(), поскольку ваша функция __autoload () вызывается только в том случае, если она еще не загружена.

1 голос
/ 11 октября 2010

[Редактировать: удалено неверное предложение относительного пути - w3d обнаружил реальную проблему.Оставляя здесь остальные только для информации]

Также вы можете изменить require_once в функции автозагрузки на require - по определению функция будет работать, только если класс еще не был включен.

Вы можете значительно упростить автозагрузку, используя путь включения, так как тогда PHP проверит для вас разные места.Например, что-то вроде этого:

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

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