1

これは、frontController を作成する最初の試みであり、いくつかの小さな問題に遭遇しました。

最初に、私のサイトがどのように見えるかの印象を述べさせてください。ブラウザで 開くhttp://mysite.com/testと、サーバーは GET パラメータ $controller (test) を使用して index.php を呼び出します。これは .htaccess によって行われます。index.php では、クラス $controller のインスタンスが作成されます。これには、PHP の __autoload 関数を使用します。したがって、コードは次のようになります。

$controller = $_GET["controller"];

function __autoload($controller)
{
    include("controllers/$controller.php");

    if(!class_exists($controller, false))
    {
        eval
        ('
            class '. $controller . '
            {
                public function __construct()
                {
                    include("404.html");
                    exit();
                }
            }
        ');
    }
}


$application = new $controller;

私が提供したコードを見ると、その中にeval()が含まれていることに気付いたかもしれません。これを使用して、$controller クラスが存在しない場合の致命的なエラーを回避し、代わりに 404 を表示します。

そして、ここから楽しみが始まります:誰かが次のような URL を入力すると

http://mysite.com/ImATroll!:D

あるだろう

解析エラー: 構文エラー、予期しない '!'

と...

致命的なエラー: クラス 'ImATroll!:D' が見つかりません

質問は次のとおりです。どうすればこれをキャッチできますか? クラス名に許可されている文字のみを含むように $controller 変数をエスケープするにはどうすればよいですか?

4

4 に答える 4

4

その部分を単にドロップevalして、その部分で 404 に直接リダイレクトします。

または、1 つ(非動的) 404- ContentNotFoundController を作成し、必要に応じてそれを使用 / 生成します (クラス名が存在しない場合)。

于 2012-06-18T09:22:58.030 に答える
2

class_exists(class_exists は autoload 関数を呼び出します)の呼び出しの前に試してみませんか? new $controller;false の場合は、include('404.html');

function __autoload($classname){

   $file = "controllers/$classname.php";
   if(is_file($file))
    include_once($file);

}

...ただし、?controller=../htpasswd を渡すなどのセキュリティの問題に注意してください。英数字以外のすべての文字を削除して、クラス名をサニタイズする必要があります-のように$classname = preg_replace('/[^A-Za-z0-9]/', '', $classname);

于 2012-06-18T09:23:43.850 に答える
1

見つからないクラスのクラスを作成するだけです。

if(!class_exists($controller, false))
{
    $controller = "NotFound";
    include("controllers/NotFoundController.php");
}

許可されているコントローラーをホワイトリストに登録し、in_array()そのクラス名を認識しているかどうかを確認することもできます。その欠点は、追加するクラスごとにホワイトリストを変更する必要があることです。

可能なクラス名をフィルタリングする正規表現を作成することもできます。

于 2012-06-18T09:26:39.343 に答える
1

実際には、autoload 関数から例外をスローすることができます (ps:代わりにspl_autoload_registerを使用してください)。

この例外はキャッチ可能であるため、「デフォルト」機能を提供できます。

これははるかに優れた方法ですが、この偽のコントローラーをどうしても作成したい場合は、代わりに class_alias を使用する必要があります。

于 2012-06-18T09:32:32.010 に答える