Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/237.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 访问$\u POST或其他超全局时是否可能触发错误?_Php_Superglobals - Fatal编程技术网

Php 访问$\u POST或其他超全局时是否可能触发错误?

Php 访问$\u POST或其他超全局时是否可能触发错误?,php,superglobals,Php,Superglobals,我在backburner上有一个框架项目,我想强制使用输入类来访问所有超全局文件,比如$\u POST,$\u GET和$\u服务器。这里的一位女士提醒了我这件事 该类将做一些事情来确保没有恶意或意外,并提供一种访问项目的方法,而无需每次都使用isset()。它可能会根据配置做其他事情,也可能会清除超全局。我也不喜欢这样的事实,我想在价值观中强制执行完整性。我希望这个类被专门使用,并希望在未使用时警告开发人员 我的问题是,我担心答案是“不”: 是否有可能在访问其中一个超全局时访问?例如: $my

我在backburner上有一个框架项目,我想强制使用
输入
类来访问所有超全局文件,比如
$\u POST
$\u GET
$\u服务器
。这里的一位女士提醒了我这件事

该类将做一些事情来确保没有恶意或意外,并提供一种访问项目的方法,而无需每次都使用
isset()
。它可能会根据配置做其他事情,也可能会清除超全局。我也不喜欢这样的事实,我想在价值观中强制执行完整性。我希望这个类被专门使用,并希望在未使用时警告开发人员

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

是否有可能在访问其中一个超全局时访问?例如:

$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"

将一个对象分配给$\u POST变量并使用神奇的方法如何


$\u POST=new%your class%()

它只会触发一个通知,但如果您首先将所有超全局键/值复制到一个对象中,然后执行以下操作:

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

此后,对这些超全局变量的任何读取访问都将失败。为了禁止写入,您可以在这些变量(即名称为$\u GET、$\u POST、$\u SERVER)上实例化您选择的对象。要通过[$key]数组操作符保持这些对象的可访问性,它们应该是实现接口的对象的实例。

您可以使用
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;
    }
}

这基本上是@Baba已经展示的内容,但我已经在一些项目中使用了类似的输入包装器。它非常适合小项目,但不可否认,我仍然需要克服使用上的不情愿。不过,它确实简化了清理和审计


ArrayAccess
方法就是您所需要的。在运行时防止输入注入或覆盖偏移集就足够了。虽然我只是打印通知,但还是允许的

但基本上是为了消毒。例如,
$\u REQUEST[“key”]
的任何原始访问都将通过默认筛选器,但您也可以在运行时简单地调用各种筛选器链:

 print $_POST->html->text["comment"];
最近,我一直在允许一个受限制的寄存器\u globals工作,一次本地化多个变量。使用PHP 5.4语法,它看起来非常有趣:

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

如果在启动时只包装$\u GET、$\u POST、$\u请求,那么您已经完成了目标。唯一的语法缺陷是您不能再使用
empty($\u POST)
,这类包装器仍然允许所有其他原始数组访问。

这并不能阻止用户再次完全覆盖
$\u POST
,但这是一种有趣的方法+1是的,这其实很聪明!今天下午我将试一试。事实上,如果他使用的是PHP5,他甚至可以在那个新的类中使用。@MaximeMorin:这是一些非常疯狂的东西,非常感谢链接,我做梦也想不到这是可能的。我仍然对覆盖方面感到好奇,因为
$\u POST=array()
会禁用我以前的作业。表示这是一种可能性。我希望用户知道错误的原因,而不仅仅是困惑,但感谢您的想法。感谢您的附录,看起来它很可能正是我所寻找的,我会检查它。这是辉煌的,但对我来说是新的领域。除了
$\u POST=“Hello World”之外,一切都很好(指定特定键会触发错误)-有什么想法吗?@Wesley谢谢。。这可以适用于所有超级全局变量,因为它们都是阵列。我尝试添加一个
\u set
函数只是为了让它见鬼,但这也不起作用,仍然可以完全重新分配
$\u POST/super
。这是怎么做到的?我很想知道如何做到这一点,这将是拼图的最后一块。使用
setRequest
方法……:)您可以重新分配
$\u POST/SUPER
非常感谢,稍后将详细查看代码,但这非常酷-我从未想过这是可能的。我想用一个带有静态方法的类来阅读,只要我们使用“超全局”和愚蠢的语法,就可以了,对吧?非常感谢分享这个。我正在考虑在开发/调试模式下打印通知,甚至可能像在生产模式下打印致命错误一样苛刻。。。即使记录了无声错误,也似乎很危险。没有机会阻止
$\u POST='something'但是,对吗?对于后者,您可能可以使用
\uu destruct()
。但使用PHPs垃圾收集器,这只会在事实发生后才显示出来;充其量只用于日志记录。就我个人而言,我确实喜欢这种奇怪的语法,因为它将即时清理和访问内容的正确位置可视化。对于一个项目,我还使用了一个更严格的设置,对于未过滤的访问,会出现致命错误和异常。因此,这样的包装确实增加了一些灵活性。