0

所以我写了这个函数:

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 绘画”我只需要它来确保不会出现在产品标题中不会出现的古怪字符(如分号或引号“”等) t进入mysql.我做错了什么?

4

1 回答 1

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包含什么。当您以这种方式使用占位符和绑定参数时,mysqli 将 SQL 和数据分开,因此不可能*破坏东西。里面的任何东西都可以很好地进入数据库。您可以对更新和删除执行几乎相同的操作,而选择查询则略有不同。

* 在一些非常晦涩的情况下,可能会中断。但是你基本上必须有一个非常糟糕的环境的完美风暴,包括古代版本的 MySQL 和中国以外没有人使用的字符集。

于 2012-12-06T03:30:53.650 回答