1

如果我的网站上有问题,如果用户使用空间,他们可以发布空消息。

代码:

if (isset($_POST['submit'])) {

  // check for empty fields
  if (empty($_POST['headline']) || empty($_POST['text']) ||
      empty($_POST['forum_id'])) {
      header("Refresh: 2; url=/add-thread"); 
      die('You must fill out every field.');
  }

// No errors? Save.
else {
$headline = mysql_real_escape_string($_POST['headline']);
$text = mysql_real_escape_string($_POST['text']);

mysql_query("INSERT INTO threads (headline, text, date, forum_id, user_id)
             VALUES ('$headline', '$text', NOW(), '$_POST[forum_id]', '$user[id]')");

header("Location: /thread/".mysql_insert_id()."");
}

}

我怎样才能解决这个问题?

4

7 回答 7

9

trim()文本输入。您可以像这样轻松地做到这一点:

// get input vars and trim space
$callback = array('filter' => FILTER_CALLBACK, 'options' => 'trim');
$fields = filter_input_array(INPUT_POST, array(
    'headline' => $callback,
    'text'     => $callback,
    'forum_id' => $callback,
));

// check for empty fields by counting how many are set
if ( count($fields) != count(array_filter($fields)) ) {
    // something was unset
}
于 2009-01-31T23:41:53.130 回答
3

空函数检查符合设定条件的变量,来自手册

如果 var 具有非空且非零值,则返回 FALSE。

以下内容被认为是空的:

  • ""(一个空字符串)

  • 0(0 为整数)

  • "0" (0 作为字符串)

  • 无效的

  • 错误的

  • array() (一个空数组)

  • 变量$变量;(声明的变量,但在类中没有值)

您的 $_POST 字段实际上包含类似这样的内容

"   "; 

这不是空字符串,而是一个用空白字符填充的字符串。

在使用空()之前,修剪()您发布的值中的空白

$trimmed_post = array();
foreach($_POST as $key=>$value){
    $trimmed_post[$key] = $value;
}
if(!empty($trimmed_post['headline'])){
    //...
}

您不需要将新值放入新数组中,但我不喜欢更改自动生成的超全局变量中的内容。

最后一点,你不能做这样的事情

if(!empty(trim($_POST['headline']))){
   //...
}

因为空函数期望传递一个实际变量。你可以做这样的事情

if('' != trim($_POST['headline'])){
//...
}

这可能是最好的方法。您减少了需要调用的函数数量,用户可以发布值为 0 的条目,并且代码更明确地说明了它的作用。您将看到的另一种形式是

if(trim($_POST['headline'])){

}

这是因为 PHP 将空字符串 ('') 评估为 false,将非空字符串评估为 true。我倾向于避免这种形式,因为我发现很多 PHP 错误都是围绕着对相等运算符如何从某些类型中获取布尔值的误解而出现的。明确有助于减少此类错误的发生。

于 2009-02-01T03:14:30.140 回答
1

快速说明:您正在将值$_POST['forum_id']注入 SQL;这不是一个好主意,因为用户可以根据需要操纵该值,即使它来自隐藏字段。明智的做法是转义该值,或者至少将其传递intval()并确保它是一个整数(假设整数帖子标识符)。

于 2009-02-01T00:23:13.390 回答
1

我同意修剪是要走的路。这是一个更简单的方法:

$_POST = array_map('trim', $_POST);
于 2009-02-01T02:20:23.870 回答
0

尝试

if (!empty($_POST['headline']) && !empty($_POST['text']) &&
!empty($_POST['forum_id']))

对于逻辑。

不过,您必须切换它。

更新澄清:

if (isset($_POST['submit']) && !empty($_POST['headline']) && 
!empty($_POST['text']) && !empty($_POST['forum_id'])) {

    $headline = mysql_real_escape_string($_POST['headline']);
    $text = mysql_real_escape_string($_POST['text']);

    mysql_query("INSERT INTO threads (headline, text, date, forum_id, user_id)
         VALUES ('$headline', '$text', NOW(), '$_POST[forum_id]', '$user[id]')");

    header("Location: /thread/".mysql_insert_id()."");
}
else
{
  header("Refresh: 2; url=/add-thread"); 
  die('You must fill out every field.');    
}

}

于 2009-01-31T23:46:38.360 回答
-1

在检查提交后:

foreach ( $_POST as $key => &$value ) $value = trim($value);

针对提问者的评论进行编辑:

奇怪的是它没有像上面那样工作。这是我确认它的练习。

tbramble@wayfarer:~$ php -a
Interactive shell

php > $arr = array('one',' two', ' three ');
php > print_r($arr);
Array
(
    [0] => one
    [1] =>  two
    [2] =>  three 
)
php > foreach ( $arr as $key => &$value ) $value = trim($value);
php > print_r($arr);
Array
(
    [0] => one
    [1] => two
    [2] => three
)    

必须与处理超全局而不是普通数组有关。

于 2009-01-31T23:59:33.250 回答
-1

应用程序启动后,我会修剪每个$_GET&$_POST变量。尝试这样的事情:

function trimArray(&$array) {
    if (empty($array)) {
        return;
    }

    foreach ($array as $k => $v) {
        if (! is_array($v)) {
            $array[$k] = trim($v);
        } else {
            trimArray($v);
        }
    }
}

if (! empty($_GET)) {
    trimArray($_GET);
}
if (! empty($_POST)) {
    trimArray($_POST);
}
于 2009-02-01T02:12:11.657 回答