提问人:Pekka 提问时间:11/28/2009 更新时间:11/28/2009 访问量:7062
为什么 filter_input() 不完整?
Why is filter_input() incomplete?
问:
我目前正在开发一个基于PHP的CMS,当我在做这件事时,我想把用户输入的所有处理和清理工作转移到一个中心位置。(目前,这里是 _REQUEST 美元,那里是 _GET 美元,依此类推)。
我非常喜欢 filter_input(),并希望将其用于基本的卫生设施,但我不清楚此功能是否真的可用于生产。例如,文档将以下参数命名为 $type
INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV, INPUT_SESSION (not implemented yet) and INPUT_REQUEST (not implemented yet).
该函数自 5.2.0 以来就存在,为什么两个关键元素尚未实现?如果我想从 $_REQUEST 获取数据,您必须使用用户贡献的注释中的解决方法。这有什么特殊原因吗?这个功能还在某种测试版中吗?作为处理传入数据的第一个调用是否值得信赖?
也许熟悉PHP开发过程的人可以对此有所了解。
答:
在编程中,您必须尽可能限制您的输入。这也适用于数据源。_REQUEST 美元包含 _GET 美元、_POST 美元和 _COOKIE 美元中的所有内容,这可能会导致问题。
例如,如果CMS的插件在其中一个插件中引入了一个新的特殊密钥,而该密钥恰好作为另一个插件中的有意义的密钥存在,会发生什么?
所以永远不要使用 _REQUEST 美元。使用 _GET 美元、_POST 美元或 _COOKIE 美元,以适合您的情况为准。 尽可能严格是一种很好的做法,这与PHP无关,但与一般的编程有关。
评论
我想将用户输入的所有处理和卫生工作转移到一个中心位置
是的,那该有多可爱。这是做不到的。这不是文本处理的工作方式。
如果要将文本从一个上下文插入到另一个上下文中,则需要使用正确的转义符。(mysql_real_escape_string用于MySQL字符串文字,htmlspecialchars用于HTML内容,urlencode用于URL参数,其他用于特定上下文)。在脚本开始时,当你进行筛选时,你不知道你的输入将在哪里结束,所以你不知道如何转义它。
也许一个输入字符串既进入数据库(需要 SQL 转义)又直接进入页面(需要 HTML 转义)。没有一种逃脱可以涵盖这两种情况。您可以一个接一个地使用这两个转义符,但是 HTML 中的值将出现奇怪的反斜杠,并且数据库中的副本将充满与号。这种错误编码的几轮,你会遇到这样的情况,每次你编辑一些东西时,都会出现一长串。\\\\\\\\\\\\\\\\\\\\
&
在开始时,您可以一次性安全地进行过滤的唯一方法是完全删除所有需要在您将要使用它们的上下文中转义的字符。但这意味着你的HTML中没有撇号或反斜杠,你的数据库中没有与号或小于号,而且可能还必须去掉一大堆其他对URL不友好的标点符号。对于一个不采用任意文本的简单网站,您也许可以侥幸逃脱。但通常不会。
因此,只有当一种类型的文本进入另一种类型的文本时,您才能即时逃脱。避免此问题的最佳策略是尽可能避免将文本连接到其他上下文中,例如,使用参数化查询而不是 SQL 字符串生成,并使用漂亮的短名称定义函数以减少键入的工作量,或者使用默认情况下 HTML 转义的替代模板系统。echo(htmlspecialchars())
评论
“输入过滤”或“卫生”是一个荒谬的想法。远离它。
解释和进一步讨论
评论
INPUT_SESSION
并且没有实现(尽管呈现了一个多维用例,并且默认情况下与其他用例不同)。用于 .我可能还会注意到,也没有“INPUT_DATABASE”,但你仍然有责任。再次尝试.INPUT_FILES
$_FILES
filter_var_array()
$_SESSION
filter_var_array()