php:我的正则表达式无法验证简单的短语?

时间:2012-12-06 02:41:36

标签: php regex php4

所以我写了这个函数:

function validate_text($text,$min,$max,$include_spaces=true)
{
    $match = array();
    $regex = ($include_spaces)?"/[a-zA-Z0-9 .\-_]":"/[a-zA-Z0-9.\-_]";
    if($max<=0)
    {
        $regex = sprintf($regex."{%d,}/",$min);
    }
    else
    {
        $regex = sprintf($regex."{%d,%d}/",$min,$max);
    }
    if($include_spaces)
    {
        preg_match($regex,$text,$match);
    }
    else
    {
        preg_match($regex,$text,$match);
    }
    return (implode($match)==$text);
}

并使用它:

  (validate_text($_POST['prod_name'],10,100,true)

我不能让它验证简单的标题“绘画由cbkirby”我只需要它确保没有古怪的字符,否则不会出现在产品标题中(如simecolons或引号'“等)不会进入mysql。我做错了什么?

1 个答案:

答案 0 :(得分:1)

我不确定为什么要这么做,当你可以说“如果这个模式匹配”并在两端锚定模式。 preg_match已经告诉您模式是否匹配;你所要做的就是告诉它尝试匹配整个字符串。 :)

function validate_text($text,$min,$max,$include_spaces=true)
{
    $chars = ($include_spaces) ? "[a-zA-Z0-9 .\-_]" : "[a-zA-Z0-9.\-_]";
    if ($max <= 0) $max = '';
    $regex = "/^{$chars}{{$min},{$max}}$/";
    return !!preg_match($regex, $text);
}

至于你原来的功能,虽然可能是啰嗦,但似乎有效。您可能希望var_dump($_POST['prod_name'])确保它符合您的想法。 (请注意,如果prod_name位于查询字符串中,您将在$_GET而不是$_POST中找到它。)


现在...... 目标 ...

如果你这样做是为了保持SQL中的“坏”字符,那就有点误导了。例如,完全可以想象名称中包含撇号。我很少在一个网站上烦恼,而不是在我花时间输入一堆数据时,即使它是正确的,我也会得到一些“对不起,你的数据无效”的消息。 :P“这个普通且完全合法的字符无效”听起来像“我们的网站没有正确处理数据”。

就个人而言,除非我有良好的商业理由限制数据,否则我不。保持SQL清洁并不是商业原因,因为保持安全并不困难......

$db = new mysqli('localhost', 'dbusername', 'dbpassword', 'dbname');
$stmt = $db->prepare("
    INSERT INTO products (prod_title, other_stuff)
    VALUES (?, ?)
");
$stmt->bind_param('ss', $_POST['prod_title'], $_POST['other_stuff']);
$stmt->execute();

此时,我甚至不必关心prod_titleother_stuff包含的内容。当你使用占位符并以这种方式绑定params时,mysqli将SQL和数据分开,所以不可能*破坏东西。无论在那里,它都会很好地进入数据库。对于更新和删除,您可以做同样的事情,对于选择查询,您可以略微不同。

*在一些非常模糊的情况下,它可能会破裂。但是你必须要有一个非常糟糕的风暴的完美风暴,包括古代版本的MySQL和中国境外没有人使用过的字符集。