Php 访问$\u POST或其他超全局时是否可能触发错误?
我在backburner上有一个框架项目,我想强制使用Php 访问$\u POST或其他超全局时是否可能触发错误?,php,superglobals,Php,Superglobals,我在backburner上有一个框架项目,我想强制使用输入类来访问所有超全局文件,比如$\u POST,$\u GET和$\u服务器。这里的一位女士提醒了我这件事 该类将做一些事情来确保没有恶意或意外,并提供一种访问项目的方法,而无需每次都使用isset()。它可能会根据配置做其他事情,也可能会清除超全局。我也不喜欢这样的事实,我想在价值观中强制执行完整性。我希望这个类被专门使用,并希望在未使用时警告开发人员 我的问题是,我担心答案是“不”: 是否有可能在访问其中一个超全局时访问?例如: $my
输入
类来访问所有超全局文件,比如$\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垃圾收集器,这只会在事实发生后才显示出来;充其量只用于日志记录。就我个人而言,我确实喜欢这种奇怪的语法,因为它将即时清理和访问内容的正确位置可视化。对于一个项目,我还使用了一个更严格的设置,对于未过滤的访问,会出现致命错误和异常。因此,这样的包装确实增加了一些灵活性。