5

私はphp mvcを試していますが、次の問題に悩まされています。私のリクエストとルータークラスは本当にシンプルで、サブフォルダーからのコントローラー呼び出しを処理できるようにテーマを拡張したいと思います。コントローラークラス関数は、get と post をスローして送信する URL 変数を取得できる必要があります。

私のルーターは次のようになります

class Router{

    public static function route(Request $request){


        $controller = $request->getController().'Controller';

        $method = $request->getMethod();

        $args = $request->getArgs();


        $controllerFile = __SITE_PATH.'/controllers/'.$controller.'.php';


        if(is_readable($controllerFile)){
            require_once $controllerFile;

            $controller = new $controller;


            if(!empty($args)){
                call_user_func_array(array($controller,$method),$args);
            }else{  
                call_user_func(array($controller,$method));
            }   
            return;
        }

        throw new Exception('404 - '.$request->getController().'--Controller not found');
    }
}

およびリクエストクラス

    private $_controller;


    private $_method;

    private $_args;

    public function __construct(){

        $parts = explode('/',$_SERVER['REQUEST_URI']);


        $this->_controller = ($c = array_shift($parts))? $c: 'index';
        $this->_method = ($c = array_shift($parts))? $c: 'index';

        $this->_args = (isset($parts[0])) ? $parts : array();

    }

    public function getController(){

        return $this->_controller;

    }
    public function getMethod(){

        return $this->_method;

    }
    public function getArgs(){

        return $this->_args;
    }
}

問題は、スローされた ajax をコントローラ メソッドに送信しようとすると、URL 構造が原因で認識されないことです。例えば

index/ajax?mod_title=shop+marks&domain=example

見えるだけで受け入れられる

index/ajax/shop+mark/example
4

4 に答える 4

10

コードにはLFI 脆弱性と呼ばれるものが含まれており、現在の状態では危険です。
として使用できるものをホワイトリストに登録する必要があります。$controllerそうしないと、攻撃者が NUL バイトを使用して何かを指定しようとする可能性があり、ディレクトリを上って、 、構成ファイルなど、含めるべきではないファイルを含める可能性があります/etc/passwd

ルーターは安全に使用できません。注意してください!

編集:ホワイトリストの例

$safe = array(
    'ajax',
    'somecontroller',
    'foo',
    'bar',
);
if(!in_array($this->_controller, $safe))
{
    throw new Exception(); // replace me with your own error 404 stuff
}
于 2012-05-24T13:52:50.783 に答える
2

Request クラスはコントローラー、アクション、および引数を識別するために URI セグメント アプローチを使用するため、$_GET や $_REQUEST などのグローバル変数は Request 内から考慮されません。

必要なことは、リクエスト コードにいくつか追加することです。具体的には:

次の行を削除します。

$this->_args = (isset($parts[0])) ? $parts : array();

そして、次を追加します。

$all_parts = (isset($parts[0])) ? $parts : array();
$all_parts['get'] = $_GET;
$this->_args = $all_parts;

このように、$_GET (つまり、url 経由で渡される変数) 変数は、$args にあるため、呼び出されたアクションで使用できます (実際には $args['get'] として使用できます。これは保持する配列です)。 $args['get']['domain']) を使用して domain=example にアクセスできるようになります。

もちろん、次のような Request クラス (クエリなど) にもう 1 つのメソッドを追加できます。

public function query($var = null)
{
    if ($var === null)
    {
        return $_GET;
    }
    if ( ! isset($_GET[$var]) )
    {
        return FALSE;
    }
    return $_GET[$var];
}

このようにして、URL から 1 つの変数 (例: $request->query('domain')) または $_GET 配列全体 ($request->query()) を取得できます。

于 2012-05-24T11:25:23.140 に答える
0

これは、php が$_GET自動的に "?mod_title=..." を配列に入れるためです。関数は、またはgetArgs()をチェックする必要があります。$_GET$_POST$_REQUEST

最小限の MVC アプローチを試している場合は、rasmus の例をご覧ください: http://toys.lerdorf.com/archives/38-The-no-framework-PHP-MVC-framework.html

ユース ケースがより複雑になる場合は、Zend (http://framework.zend.com/manual/en/zend.controller.html) または Symfony (https://github.com/symfony) を参照してください。 /symfony/tree/master/src/Symfony/Component/Routing) が処理を行います。

于 2012-05-24T09:47:19.467 に答える