1

PHP 5.3.3-pl1-gentoo (cli)(构建:2010 年 8 月 17 日 18:37:41)

大家好,我在项目的主文件(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}):无法打开流:第 20 行的 /home/beep/work/php/hauthd/index.php 中没有这样的文件或目录 PHP 致命错误: require_once():在 /home/beep/work/php 中打开所需的 './../shared/SqlTool.php}' (include_path='.:/usr/share/php5:/usr/share/php') 失败/hauthd/index.php 第 20 行

所以它不会对扩展类的任何请求做出反应。

最后一个想法:把 spl_autoload_register 放到每个文件中。但不能把它放到“扩展”指令本身!

PS 可能使用工厂模式重写 SqlTool.php,因此它会自动返回项目特定类的实例,但这似乎不是最好的方法,或者它是..?

4

2 回答 2

2

如果 SqlHD 扩展了 SqlTool,那么你的 __autoload() 函数应该自动包含这个。

请注意,您的文件名中有一个额外的“}”,这可能会搞砸。(您还将“n”复制到第二个代码片段中。)

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

顺便说一句,我认为您只需要require()在 __autoload() 函数内部而不是 __autoload() 函数require_once(),因为只有在尚未加载时才会调用 __autoload() 函数。

于 2010-10-10T22:34:32.727 回答
1

[编辑:删除了不正确的相对路径建议 - w3d 发现了真正的问题。剩下的留在这里仅供参考]

您也可以require_once将 autoload 函数中的 更改为 just require- 根据定义,该函数仅在尚未包含该类时才运行。

您可以通过使用包含路径大大简化您的自动加载,因为 PHP 会为您检查不同的位置。例如这样的:

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

function __autoload($className) {
    require "$className.php";
}
于 2010-10-10T22:47:29.530 回答