【问题标题】:Running a query with missing variables运行缺少变量的查询
【发布时间】:2016-01-26 07:46:14
【问题描述】:

此脚本根据 HTML 表单中的可选字段选择数据。尽管它们是可选字段,但至少必须输入 1,因为输入的字段越多,您获得单个结果的可能性就越大。对于测试,我有两个名字和姓氏相同但 ID 和手机号码不同的记录。输入姓名的那一刻,给出了2个字段...正确,但是输入手机或ID时,仍然显示两个结果。

我尝试在 SQL 查询中读取传递缺失的变量,但还没有走多远。有什么明显的错误吗?

谢谢

<?php

include "checkmysqlconnect.php";

$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
$mobile = $_POST['mobile'];
$attendid = $_POST['attendid'];
$search = $_POST['search'];

if ($search == "Search") {
if ($firstname == '' AND $lastname == '' AND $attendid == '' AND $mobile == '') {
    header("Location: searchattendform.php?result=1");
        $error = true;
    }

    if($error != true) {

$sql = "SELECT * FROM `attend` WHERE `firstname` = '".$firstname."' AND `lastname` = '".$lastname."' AND `attendid` = '".$attendid."' AND `mobile` = '".$mobile."'";
$query = mysql_query($sql);
$count = mysql_num_rows($query);

if ($count > 1) {
while($value = mysql_fetch_assoc($query)) {
    echo "More than one attendee with this name. Entering more details will help narrow down results.";
    echo "<tr><td>".$value['attendid']."</td><td>".$value['wristband']."</td><td>".$value['firstname']."</td><td>".$value['lastname']."</td><td>".$value['telephone']."</td><td>".$value['mobile']."</td><td>".$value['address1']."</td><td>".$value['address2']."</td><td>".$value['town']."</td><td>".$value['postcode']."</td><td>".$value['email']."</td><td>".$value['medical']."</td></tr>";
} } else {
if ($count == 0) {
    header("Location: searchattendform.php?result=2");
} else {
    if ($count == 1) {
        ($value = mysql_fetch_assoc($query));
        echo "<tr><td>".$value['attendid']."</td><td>".$value['wristband']."</td><td>".$value['firstname']."</td><td>".$value['lastname']."</td><td>".$value['telephone']."</td><td>".$value['mobile']."</td><td>".$value['address1']."</td><td>".$value['address2']."</td><td>".$value['town']."</td><td>".$value['postcode']."</td><td>".$value['email']."</td><td>".$value['medical']."</td></tr>";
    } else {
        echo "The was an issue searching attendees. Please contact SOFia Admin.";
        } }
}
}
}

?>

【问题讨论】:

  • mysql_query 已弃用,您可以通过将用户输入的数据直接传递到您的查询中来进行 sql 注入攻击
  • 准备好的语句和绑定占位符没那么难

标签: php html mysql forms


【解决方案1】:

您遇到的一个问题是您的查询总是检查所有变量:

$sql = "SELECT * FROM `attend` WHERE `firstname` = '".$firstname."' AND `lastname` = '".$lastname."' AND `attendid` = '".$attendid."' AND `mobile` = '".$mobile."'";

您可能希望将其分解并动态构建,如下所示:

$sql = "SELECT * FROM `attend` WHERE ";

$whereArray = [];
if ($lastName){
    $whereArray[] = "`lastname` = '".$lastname."'";
}
if ($firstname){
    $whereArray[] = "`firstname` = '".$firstname."'";
}

//etc...

$sql .= join(" AND ", $whereArrray);

【讨论】:

    【解决方案2】:

    您需要对其进行修改以使用参数化,但这应该会让您朝着正确的方向前进:

    include "checkmysqlconnect.php";
    
    ((isset($_POST['firstname']) && $_POST['firstname'] != '') ? $firstname = '%'.$_POST['firstname'].'%' : null); //prevents unneeded variables
    
    ...
    
    if (!(isset($firstname) or isset($lastname) or isset($attendid) or isset($mobile))) { //checks that at least one variable has been provided
    
    ...
    
    $sql = "SELECT * FROM `attend` WHERE 1=1"; //returns all; necessary for building the query since you have an unknown number of parameters
    (isset($firstname) ? $sql .= " AND `firstname` like '".$firstname."': null); //adds to the query only if the variable exists
    
    ...
    ?>
    

    【讨论】:

      【解决方案3】:

      我强烈推荐使用某种数据库包装类。这将有助于为您生成 SQL。为什么这是一个好主意还有很多其他原因。

      有很多 MySQL 包装器,大多数框架都有一个。例如,您可以尝试 CodeIgniter,这是一个安装和使用非常简单的框架。然后,要创建查询,您可以执行以下操作:

      <?php
      
      if(isset($_POST['firstname']) && !empty($_POST['firstname'])) {
        $this->db->where('firstname', $_POST['firstname']);
      }
      
      if(isset($_POST['lastname']) && !empty($_POST['lastname'])) {
        $this->db->where('lastname', $_POST['lastname']);
      }
      
      ...
      
      $results = $this->db->>get('attend');
      foreach($results->result() as $row)
      {
          echo $row->firstname;
      }
      
      ?>
      

      【讨论】:

        【解决方案4】:

        尝试放置 var_dump($sql);死();在 $sql 语句之后并测试返回的内容。

        【讨论】:

        • $error = true;应该在标头重定向之前定义。
        • $error = true; header("位置:searchattendform.php?result=1");
        • 并定义 $error = false;在包含语句之后(包括“checkmysqlconnect.php”;)
        猜你喜欢
        • 2020-04-06
        • 2016-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-29
        相关资源
        最近更新 更多