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 を見つけることができず、何らかの理由でメイン ファイルで定義された autoload ルーチンを使用しないためです。

私はこれを試しました:

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}): ストリームを開くことができませんでした: No such file or directory in /home/beep/work/php/hauthd/index.php 行 20 PHP 致命的なエラー: require_once(): /home/beep/work/php で必要な './../shared/SqlTool.php}' (include_path='.:/usr/share/php5:/usr/share/php') を開くことができませんでした/hauthd/index.php 20 行目

したがって、拡張クラスからのリクエストには反応しません。

最後の 2 番目のアイデア: spl_autoload_register を各ファイルに配置します。ただし、「extends」ディレクティブ自体に配置することはできません!

PSは、Factoryパターンを使用してSqlTool.phpを書き換えて、プロジェクト固有のクラスのインスタンスを自動的に返す可能性がありますが、それは最善の方法ではないようです..?

4

2 に答える 2

2

SqlHDがSqlToolを拡張する場合、__ autoload()関数はこれを自動的に含める必要があります。

ファイル名に余分な「}」が含まれていることに注意してください。これはおそらくこれを台無しにしています。(2番目のコードスニペットに貼り付けた「n」もコピーします。)

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

余談ですが、__ autoload()関数は、まだロードされていない場合にのみ呼び出されるためrequire()、ではなく、__ autoload()関数内に入れるだけでよいと思います。require_once()

于 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 に答える