5

Input私はこのフレームワークプロジェクトをバックバーナーに置いており、クラスの使用を強制して、、などのすべてのスーパーグローバルにアクセスしたいと考えて$_POST$_GETます$_SERVER。ここでの最近の質問はそれについて私に思い出させました。

クラスは、悪意のあるものや予期しないものがないことを確認するためにキーを少しクリーンアップし、毎回使用する手間をかけずにアイテムにアクセスする方法を提供しますisset()。構成によっては他のことを行う場合があり、スーパーグローバルもクリアする可能性があります。また、スーパーグローバルが読み取り専用ではないという事実も気に入らないので、値の整合性を強制したいと思います。このクラスを排他的に使用し、使用されていない場合は開発者に警告したいと思います。

私の質問はこれです、そして私は答えが「いいえ」であるのを恐れます:

スーパーグローバルの1つにアクセスしたときにエラーをトリガーすることは可能ですか?例えば:

$myvar = $_POST['key'];
// Prints "Error: POST cannot be accessed directly, use the Input class instead"

またはスーパーグローバルに書き込むとき?:

$_POST['key'] = 'myvalue';
// Prints "Error: POST data cannot be modified"
4

4 に答える 4

6

使用できますArrayAccess

例1:

$_POST = new SUPER($_POST);
$_POST['hello'] = "Hello World"; // This would trigger error ;

例2:a.php?var=1&var2=2

$_GET = new SUPER($_GET);
echo $_GET['var'] ; // returns 1
echo $_GET['var2'] ; // returns 2

$_GET['var3'] = 2 ; //return error

使用したクラス

class SUPER implements \ArrayAccess {
    private $request = array();

    public function __construct(array $array) {
        $this->request = $array;
    }

    public function setRequest(array $array) {
        $this->request = $array;
    }

    public function offsetSet($offset, $value) {
        trigger_error("Error: SUPER GLOBAL data cannot be modified");
    }

    public function offsetExists($offset) {
        return isset($this->request[$offset]);
    }

    public function offsetUnset($offset) {
        unset($this->request[$offset]);
    }

    public function offsetGet($offset) {
        return isset($this->request[$offset]) ? $this->request[$offset] : null;
    }
}
于 2012-10-18T13:03:18.493 に答える
6

オブジェクトを $_POST 変数に割り当てて、マジック メソッドを使用するのはどうですか?

$_POST = new %your-class%();

于 2012-10-18T12:41:41.057 に答える
2

通知以上のものはトリガーされませんが、最初にすべてのスーパーグローバルキー/値をオブジェクト内にコピーしてから実行すると:

unset($_GET,$_POST,$_SERVER);

その後、これらのスーパーグローバルへの読み取りアクセスは失敗します。書き込みを禁止するには、これらの変数 (つまり、$_GET、$_POST、$_SERVER という名前) に対して選択したオブジェクトをインスタンス化できます。[$key] 配列演算子を介してこれらにアクセスできるようにするには、ArrayAccessインターフェイスを実装するオブジェクトのインスタンスにする必要があります。

于 2012-10-18T12:45:12.850 に答える
1

これは基本的に @Baba が既に紹介したものですが、いくつかのプロジェクトで同様の入力ラッパーを使用しています。小規模なプロジェクトには非常に適していますが、確かに、使用に対する抵抗を克服する必要があります。ただし、サニタイズと監査が簡単になります。

http://sourceforge.net/p/php7framework/svn/66/tree/trunk/php7/input.php?force=True
http://sourceforge.net/p/php7framework/wiki/input/

必要なのArrayAccessはアプローチだけです。実行時の入力インジェクションまたは上書きを防ぐにoffsetSetは十分です。通知を印刷しているだけですが、それでも許可します。

ただし、基本的には消毒用です。たとえば、 eg への生のアクセス$_REQUEST["key"]はデフォルトのフィルターを通過しますが、実行時にさまざまなフィルターチェーンを呼び出すこともできます。

 print $_POST->html->text["comment"];

最近、私は抑制された register_globals workaorund を許可して、一度に複数の変数をローカライズしています。PHP 5.4 の構文では、かなりおかしく見えます。

 extract( $_REQUEST->list->text[[ title, id, email ]] );
 // implicit undef-constant notices here ^^ of course

起動時に $_GET、$_POST、$_REQUEST をラップするだけで、すでに目的を達成しています。唯一の構文上の欠点は、 を使用できなくなったことですempty($_POST)。他のすべての生の配列アクセスは、そのようなラッパーによって引き続き許可されます。

于 2012-10-18T20:54:54.347 に答える