2

当我开始使用 PHP 时,我对 PHP 的松散类型和易于学习感到非常满意。但是随着我的成长,我意识到松散的类型实际上使我的脚本变得复杂而不是简化它们。现在我正在寻找可以强类型化 PHP 变量的方法,特别是输入变量($_POST$_GET$_COOKIE$_REQUEST一些$_SERVER变量)。

此外,我希望在此过程中隐藏我的验证和清理,以便我可以“忘记”SQL 注入和许多其他容易出错的验证过程。我对我想要的样子有一个粗略的草图。

首先我声明变量。最好在 OOP 中

$varClass->post->variable_name->type('STR', 'SQL', 'EMAIL');  

// or as an array  
$_MY_POST['variable_name'] = array('STR', 'SQL', 'EMIAIL');

现在我可以从预定义的 PHP GLOBAL 中删除所有未声明的变量,并使用变量类型直接在全局数组中验证和清理它们。
我还可以将未验证变量(如 emaill)的值设置为 bool false 和 un-submitted 为 null,并在数据验证期间使用它们。然而,在我离开并重新发明轮子之前,我希望:

有人可能会引导我去一个已经帮助解决我的问题的图书馆?
如果有什么理由我不应该追求这种疯狂的幻想?实现这一目标的更好和更清晰的方法?
以及您对这个想法可能有的其他一般想法?

4

3 回答 3

4

http://sourceforge.net/p/php7framework/wiki/input/

默认情况下包装超全局变量,但您也可以使用$postFilter = new input($_POST). 它应该像这样手动使用:

 $_POST->email->sql["variable_name"]
 $_POST->array->int["order_list"]

如果它看到任何 $_POST["raw"] 访问,它就会抱怨。

但您也可以预先定义过滤器列表。我会在类定义中集中执行此操作。这应该是旧应用程序的附加组件,您不想手动检查代码并重写字符串以强制数据格式或类型:

 var $__rules = array(
      "variable_name" => "email,sql",
      "order_id" => "int,range:0:500",
      "order_list" => "array,int",
 );

但我个人会避免 ->sql 过早地转义。如果可用 PDO 和参数化的 SQL 应该被使用。但当然,中央转义功能总比谨慎好。

您还可以定义自定义过滤器。例如,它采用全局函数。

于 2010-12-02T12:58:59.047 回答
4

PHP 是松散类型的

不 - 它不是松散类型的,它是动态类型的 - 存在细微差别。

实际上使我的脚本复杂化而不是简化它们

我的经历恰恰相反。

我想要我的验证和消毒...

强类型不是处理输入验证的方法,尤其是在 HTTP 之类的介质上(它是松散类型的)。对每个可能的输入进行类型验证是不切实际的——确保你可以将电子邮件地址存储在字符串中——但这并不意味着电子邮件地址的格式正确,你如何确保文件是图像?强类型如何确保开始日期早于结束日期?

虽然最近的 PHP 版本具有过滤功能,但我(以及我认识的大多数人)长期以来一直在使用我自己的 atom 输入验证库,而二阶验证(比较多个输入的相对值)需要自定义代码。您唯一应该更改输入类型的地方是不会导致数据丢失(例如字符串到数字的转换 - 但您需要确保您没有因此丢失数据)。声明输入 var 的预期类型并不比声明变量的实际类型更困难。如果您无法创建适合处理的输入的有效表示,那么您的代码不应该猜测用户的意思 - 您需要拒绝输入并通知用户/调用程序。

很多验证都可能与上下文相关 - 例如,英国的 02/12/2010 比美国的同一日期晚 10 个月。

如果您真的希望 PHP 表现得像强类型,请查看PHPLint

这样我就可以“忘记” SQL 注入

不!您验证/清理输入并根据输出的位置转换输出!用于写入 HTML 的字符串的正确表示不同于将其写入 URL 与将其写入数据库不同。

于 2010-12-02T13:19:19.147 回答
0

我为我们的应用程序编写了一个表单系统,它在很大程度上做到了这一点;

  • 我定义了所有我期望的字段和关于它们的规则(数据类型,至少,但也包括最小值、最大值、枚举等)
  • 随机数用于保护表单并确定它是否已提交
  • 当会话恢复时,每个序列化的表单都会检查是否发送了适当的随机数,如果是,则认为自己已提交
    • 然后它检查每个已知字段,获取提交的数据并验证它
    • 如果它们无效,所有字段都可以重置为默认值

这也处理表单的呈现和客户端验证规则的生成,因此我只需编写一次规则(服务器端),客户端和服务器端验证都会自动发生。数据类型规则是必须为每个字段定义的最小值。

不幸的是它不是开源的,我没有开源它的权限;我找了很长时间才找到这样的东西,但我真的找不到任何东西。Pear Quickforms 库是最接近的,但似乎并没有涵盖所有的验证,而且文档非常糟糕。

于 2010-12-02T12:32:45.323 回答