filter_var与preg_match

时间:2009-10-09 14:40:32

标签: php regex

早上好

我正在转换我正在努力的网站以符合最新版本的PHP,因此我将使用非折旧等价物替换所有ereg实例。然而,有人告诉我一个方便的内置函数PHP,名为filter_var。

我的问题是,在filter_var上使用preg_match是否有意义?因为选择一个而不是另一个有性能提升或任何其他好处,如果是这样,它们是什么?

3 个答案:

答案 0 :(得分:3)

首先,关于过滤的PHP手册页:https://php.net/manual/en/book.filter.php

第二,上下文是关键。一般来说,过滤器功能设计为使用外部输入(标量或数组)或内部输入。外部输入来自HTTP请求/ PHP引擎或表单提交等来源。

使用filter_input前缀的过滤器功能允许您绕过 $ _SERVER,$ _COOKIE,$ _POST和$ _GET superglobals。虽然您通常指定要从中获取数据的“位置”,但过滤器函数未明确使用 $ _POST,$ _GET,$ _COOKIE和$ _SERVER。您对变量/数组元素所做的更改将不会在$ _GET,$ _POST或$ _SERVER中显示,因此以这种方式使用过滤器是一种范例转换,可能会显着改变应用程序的流量。换句话说,您必须自己跟踪外部输入。我这样做是为了对外部输入进行初始消毒(剥离,替换,改变等)。我根本不再使用$ _POST,$ _GET或$ _SERVER。虽然,我仍然使用$ _FILES。

前缀为filter_var的函数用于过滤程序中已存在的任何常规数组。我在使用filter_input后使用它。在这两种情况下都可以使用许多过滤器,但您的问题是性能

如果您选择将FILTER_VALIDATE_REGEXP过滤器与任何过滤功能一起使用,我无法想象这种间接方法比直接使用preg_match()更有效。就其他过滤器而言,如果它们只是从正则表达式调用中移除了一些方法/函数,那么我无法看到的效率提高。

我认为过滤器功能是为了帮助提高在许多应用程序中发生的过滤任务的一致性而设计的。它们可能不是设计为更强效率,但它们肯定被设计为比正则表达式更强可访问(尽管我对正则表达式非常好)。我更喜欢直接了解正在发生的事情,但有些人却不关心或不关心。但是,过滤器函数为那些不了解正则表达式和其他基本Web应用程序安全过程的人打开过滤字符串的大门。

但是,人们当然可以不使用过滤功能。

更重要的是,我将过滤器功能与我自己的清洁剂和验证器类结合使用。所以,我不是要求PHP为我思考,我只是用它来增强我已经知道的怎么做(以防万一他们的功能得到了我想念的东西)。纵深防御。

总之,您最好的选择就是使用preg_match(),除非您打算将输入的流filter_input函数)更改为您的应用程序。即使这样,也不会有性能提升,但你可以绕过$ _SERVER,$ _POST和$ _GET。此外,您可以利用更简单,结构化,一致的过滤功能,并能够使用回调函数(FILTER_CALLBACK)来调用自定义,内部,方法/函数(我也这样做)。此外,您仍然可以使用FILTER_VALIDATE_REGEXP过滤器将自己的正则表达式与过滤器函数一起使用,但同样,我认为没有理由相信如果您这样做,应用程序的性能也会提高。可维护性?也许。这取决于编写代码的人。

答案 1 :(得分:2)

filter_var - 使用指定的过滤器过滤变量
preg_match - 执行正则表达式匹配

我想use可以使用filter_var来过滤变量,但作为preg_match的替代,我不认为从ereg升级是个好主意,因为filter_var不使用正则表达式而你必须重写很多功能/这样做的逻辑。

答案 2 :(得分:1)

切换到使用filter_var()实际上是一个好主意。您将无法使用现有的正则表达式,但是您可以完全消除它们。通常,我们在应用中使用的正则表达式仅用于简单的validation和过滤,这正是filter_var()函数的用途。

例如,在您的代码中,您可能已经拥有:

if (eregi('\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b', $_POST['email'])) {
    echo "valid";
}

这可以被更漂亮的版本所取代(不依赖于自定义正则表达式):

if (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
    echo "valid";
}

filter_var()函数还能够sanitize输出您正在检查的特定数据不需要的字符,并返回已清理的字符串(而不是布尔值):< / p>

$clean = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);

filter_var()的这种用法将取代ereg_replace()类型的函数。

但是,对于最简单的升级,您可以使用'p'为ereg *()系列函数添加“前缀”,这使得它们符合PCRE(因此不再在PHP 5.3 +中弃用)。