1

我在让查询工作时遇到问题(并且也在质疑查询的安全性)。

  if(isset($_POST)){
        $sql = "SELECT * FROM members WHERE";

     if($_POST['FirstName_S'] !== ''){
        $sql .= " FirstName LIKE '%" . $_POST['FirstName_S'] . "%'";
     }
     if($_POST['LastName_S'] !== ''){
        $sql .= " OR LastName LIKE '%" . $_POST['LastName_S'] . "%'";
     }
     if($_POST['Firm_S'] !== ''){
        $sql .= " OR Firm LIKE '%" . $_POST['Firm_S'] . "%'";
     }
     if($_POST['Country_S'] !== ''){
        $sql .= " OR Country LIKE '%" . $_POST['Country_S'] . "%'";
     }
     if($_POST['City_S'] !== ''){
        $sql .= " OR City LIKE '%" . $_POST['City_S'] . "%'";
     }
     if($_POST['State_S'] !== '' AND $_POST['State_S'] !== 'other'){
        $sql .= " OR State LIKE '%" . $_POST['State_S'] . "%'";
     }
  }

显然,如果 FirstName_S 未定义,则查询会中断“WHERE OR”。看起来它会有一个合乎逻辑的修复,但我已经盯着它看了太久了。

此外,还提出了 sql 注入作为一个问题,作为一个附带问题,净化输入是否足够?或者这完全是不好的做法?

4

6 回答 6

3
  if(isset($_POST)){
        $sql = "SELECT * FROM members WHERE";

     if($_POST['FirstName_S'] !== ''){
        $sql .= "OR FirstName LIKE '%" . $_POST['FirstName_S'] . "%'";
     }
     if($_POST['LastName_S'] !== ''){
        $sql .= " OR LastName LIKE '%" . $_POST['LastName_S'] . "%'";
     }
     if($_POST['Firm_S'] !== ''){
        $sql .= " OR Firm LIKE '%" . $_POST['Firm_S'] . "%'";
     }
     if($_POST['Country_S'] !== ''){
        $sql .= " OR Country LIKE '%" . $_POST['Country_S'] . "%'";
     }
     if($_POST['City_S'] !== ''){
        $sql .= " OR City LIKE '%" . $_POST['City_S'] . "%'";
     }
     if($_POST['State_S'] !== '' AND $_POST['State_S'] !== 'other'){
        $sql .= " OR State LIKE '%" . $_POST['State_S'] . "%'";
     }

    $sql=str_replace("WHERE OR","WHERE",$sql);   // quick dirty fix

  }

当然你需要清理输入,但由于你没有提到你使用哪个 MySQL API,所以我还没有添加任何清理函数。你可以看看http://php.net/mysqli_real_escape_string

于 2013-08-12T17:25:39.477 回答
2

快速修复是添加1=1到您的查询中,因此您的查询以WHERE 1=1. 这使您可以自由地将任意数量的 附加OR something到您的查询中,而不必担心省略OR第一个。

(那个 1=1 谓词不会导致任何问题;它将在解析时进行评估,并且不会出现在执行计划中。)

至于 SQL 注入,是的,这段代码很容易受到影响。如果您使用的是 mysql 接口,则使用mysql_real_escape_string函数清理 post 变量。如果您使用的是 mysqli 或 PDO(并且您应该使用),那么请使用参数化查询。

于 2013-08-12T17:41:29.120 回答
2

做其他方式如下

if(isset($_POST)){
        $sql = "SELECT * FROM members WHERE";

     if($_POST['FirstName_S'] !== ''){
        $sql_arr[]=" FirstName LIKE '%" . $_POST['FirstName_S'] . "%'";

     }
     if($_POST['LastName_S'] !== ''){
        $sql_arr[]= " LastName LIKE '%" . $_POST['LastName_S'] . "%'";
     }
     if($_POST['Firm_S'] !== ''){
        $sql_arr[]= " Firm LIKE '%" . $_POST['Firm_S'] . "%'";
     }
     if($_POST['Country_S'] !== ''){
        $sql_arr[]= " Country LIKE '%" . $_POST['Country_S'] . "%'";
     }
     if($_POST['City_S'] !== ''){
        $sql_arr[]= " City LIKE '%" . $_POST['City_S'] . "%'";
     }
     if($_POST['State_S'] !== '' AND $_POST['State_S'] !== 'other'){
        $sql_arr[]= " State LIKE '%" . $_POST['State_S'] . "%'";
     }
     if(!empty($sql_arr)){
       $sql.=implode(' OR ',$sql_arr);
}

  }
于 2013-08-12T17:26:54.897 回答
1
$stmt = $dbConnection->prepare('SELECT * FROM members WHERE FirstName LIKE ? OR LastName LIKE ? OR FIRM LIKE ? OR Country LIKE ? OR CITY LIKE ? OR STATE LIKE ?');


if($_POST['FirstName_S'] !== ''){
  $stmt->bind_param('FirstName', '%'.$_POST['FirstName_S'].'%');
} else {
  $stmt->bind_param('FirstName', '%');
}

… // do this for all your parameters

$stmt->execute();
于 2013-08-12T17:27:31.483 回答
0

我认为这可以帮助你:

if(isset($_POST)){
    $sql = "SELECT * FROM members";

 if($_POST['FirstName_S'] !== ''){
    $sql .= " WHERE FirstName LIKE '%" . $_POST['FirstName_S'] . "%'";
 }
 else {
   $sql .= " WHERE FirstName LIKE '%'";
 }
 if($_POST['LastName_S'] !== ''){
    $sql .= " OR LastName LIKE '%" . $_POST['LastName_S'] . "%'";
 }
 if($_POST['Firm_S'] !== ''){
    $sql .= " OR Firm LIKE '%" . $_POST['Firm_S'] . "%'";
 }
 if($_POST['Country_S'] !== ''){
    $sql .= " OR Country LIKE '%" . $_POST['Country_S'] . "%'";
 }
 if($_POST['City_S'] !== ''){
    $sql .= " OR City LIKE '%" . $_POST['City_S'] . "%'";
 }
 if($_POST['State_S'] !== '' AND $_POST['State_S'] !== 'other'){
    $sql .= " OR State LIKE '%" . $_POST['State_S'] . "%'";
 }

}

对于 SQL 注入,您可以查看 General_Twyckenham 评论。

于 2013-08-12T17:25:54.160 回答
0

您可以根据输入的参数组成 WHERE 命令...

if(isset($_POST)){
    $sql_where = '';
    $sql = "SELECT * FROM members ";

    if($_POST['FirstName_S'] !== ''){
        $sql_where .= (($sql_where != '')?('OR '):(''))." FirstName LIKE '%" . $_POST['FirstName_S'] . "%' ";
    }
    if($_POST['LastName_S'] !== ''){
        $sql_where .= (($sql_where != '')?('OR '):(''))." LastName LIKE '%" . $_POST['LastName_S'] . "%' ";
    }
    if($_POST['Firm_S'] !== ''){
        $sql_where .= (($sql_where != '')?('OR '):(''))." Firm LIKE '%" . $_POST['Firm_S'] . "%' ";
    }
    if($_POST['Country_S'] !== ''){
        $sql_where .= (($sql_where != '')?('OR '):(''))." Country LIKE '%" . $_POST['Country_S'] . "%' ";
    }
    if($_POST['City_S'] !== ''){
        $sql_where .= (($sql_where != '')?('OR '):(''))." City LIKE '%" . $_POST['City_S'] . "%' ";
    }
    if($_POST['State_S'] !== '' AND $_POST['State_S'] !== 'other'){
        $sql_where .= (($sql_where != '')?('OR '):(''))." State LIKE '%" . $_POST['State_S'] . "%' ";
    }
    $sql .= (($sql_where != '')?('WHERE '.sql_where):(''));
}
于 2013-08-12T18:05:08.673 回答