访问$ _POST或其他超全局时是否可能触发错误?

时间:2012-10-18 12:27:02

标签: php superglobals

我有这个框架项目在backburner上,我想强制使用Input类来访问所有超级全局,例如$_POST$_GET$_SERVERrecent question在这里提醒了我。

该类会做一点cleanup of the keys以确保没有任何恶意或意外,并提供一种访问项目的方法,而不必每次都使用isset()。它可能会根据配置做其他事情,也可能会清除超级全局。我也不喜欢superglobals are not read-only的事实,我想在值中强制执行完整性。我希望这个类可以独占使用,并且希望在没有使用时警告开发人员。

我的问题是这个,我担心答案是“不”:

当访问其中一个超全球时,是否可以trigger an error?例如:

$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 个答案:

答案 0 :(得分:6)

如何将对象分配给$ _POST变量并使用魔术方法?

$ _ POST = new%your-class%();

答案 1 :(得分: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;
    }
}

答案 2 :(得分:2)

除触发通知外,它不会触发任何内容,但如果您首先将所有超全局键/值复制到对象内,然后执行:

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

之后,对这些超全局的任何读取访问都将失败。要禁止写入,您可以在这些变量上实例化您选择的对象(即名称为$ _GET,$ _POST,$ _SERVER)。要通过[$ key]数组运算符访问它们,它们应该是实现ArrayAccess接口的对象的实例。

答案 3 :(得分: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就足够了。虽然我只是打印出通知,但仍允许它。

基本上它是用于消毒的。对例如任何原始访问例如,$_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),所有其他原始数组访问仍然允许这样的包装器。