【问题标题】:Strange behavior with SELECT WHERE A="$var" SQL [duplicate]SELECT WHERE A="$var" SQL 的奇怪行为 [重复]
【发布时间】:2016-06-24 19:18:06
【问题描述】:

我在寻找答案,但找不到答案,因为这里的问题似乎略有不同。

$vid = $_SESSION['ID_Vendor'];
echo "ID: $vid";
$q = 'SELECT business_name, vd.ID_Vendor, res.ID_RestaurantEstablishment 
  FROM restaurant res
   INNER JOIN vendor_data vd
  ON vd.ID_Vendor=res.ID_Vendor AND res.ID_Vendor="$vid" ORDER BY business_name ASC';

变量 $vid 确实有一个值(在这种情况下等于 2,但它可能不同),但是,当我专门设置时

 WHERE res.ID_Vendor=2

我的查询返回正确和预期的值列表,但是当我使用

 WHERE res.ID_Vendor="$vid"

使用“$vid”,我的价值观的回声只是空的。

下面是完整的 sn-p 代码,也用于回显输出。 感谢您的帮助。

 $vid = $_SESSION['ID_Vendor'];
 echo "ID: $vid";
 $q = 'SELECT business_name, vd.ID_Vendor, res.ID_RestaurantEstablishment 
  FROM restaurant res
   INNER JOIN vendor_data vd
  ON vd.ID_Vendor=sfe.ID_Vendor AND res.ID_Vendor="$vid" ORDER BY   business_name ASC';
 $r = mysqli_query($connection, $q);
 while ($row = mysqli_fetch_array ($r, MYSQLI_NUM)) {

  echo '>' . htmlspecialchars($row[0]) . '  ' . htmlspecialchars($row[1]) . '   ' . htmlspecialchars($row[2]) .'</option>';
}

【问题讨论】:

  • 这有什么不同吗? $q = "SELECT business_name, vd.ID_Vendor, res.ID_RestaurantEstablishment FROM restaurant res INNER JOIN vendor_data vd ON vd.ID_Vendor=res.ID_Vendor AND res.ID_Vendor=$vid ORDER BY business_name ASC";
  • 在执行之前回显您的查询,我认为问题会很明显。如果你阅读准备好的语句,你可以完全避免这个问题。
  • 达尔文,谢谢。但是,为什么准备好的声明会有所作为?我认为存储过程会起作用,不是吗?让我两个都试试。
  • 除其他外,准备好的语句会自动为您处理查询参数的引用和类型匹配。
  • 一个简单的 echo $q; 就会发现其中一个问题。观察到的行为并不“奇怪”。它定义明确且有据可查。

标签: php mysql mysqli


【解决方案1】:

PHP 无法识别撇号对 '' 中的变量。把你的变量放在“”中。例如:

"WHERE res.ID_Vendor='$vid'"

【讨论】:

  • 谢谢@ThangTD 和 Luweiq,您的解决方案解决了问题我仍然想尝试 Darwin 提出的准备好的语句,因为它们甚至可以提高安全性。
【解决方案2】:

既然我提出了这个想法,我想我应该说明一下准备好的语句的使用。

使用mysqli 会进行如下操作(假设$connection 已成功初始化):

// The indentation here is purely a matter of personal preference
$query = 'SELECT business_name, vd.ID_Vendor, res.ID_RestaurantEstablishment 
            FROM restaurant res
            INNER JOIN vendor_data vd
              ON vd.ID_Vendor = res.ID_Vendor
            WHERE res.ID_Vendor = ?
            ORDER BY business_name ASC';

$stmt = $connection->prepare($query);
$stmt->bind_param('s', $vid);  // 's' assumes $vid is string; use 'i' for int
$stmt->execute();
$res = $stmt->get_result();
while ($row = $res->fetch_array(MYSQLI_NUM))
{
    echo '>' . htmlspecialchars($row[0]) . '  ' . htmlspecialchars($row[1]) . '   ' . htmlspecialchars($row[2]) .'</option>';
}

使用PDO的成语相同。 PDO data source name (DSN) 的格式在线记录。

$conn = new PDO($dsn, $username, $password); // define these vars elsewhere
$query = 'SELECT business_name, vd.ID_Vendor, res.ID_RestaurantEstablishment 
            FROM restaurant res
            INNER JOIN vendor_data vd
              ON vd.ID_Vendor = res.ID_Vendor
            WHERE res.ID_Vendor = :vid
            ORDER BY business_name ASC';
$stmt = $conn->prepare($query);
$stmt->execute(array(':vid' => $vid));
while ($row = $stmt->fetch(PDO::FETCH_NUM))
{
    echo '>' . htmlspecialchars($row[0]) . '  ' . htmlspecialchars($row[1]) . '   ' . htmlspecialchars($row[2]) .'</option>';
}

在这两种情况下,我都将错误处理留给读者作为练习。

【讨论】:

    【解决方案3】:

    您的代码存在一些问题:


    首先,这行不通,会直接回显$vid

    echo "ID: $vid";
    

    这将返回:ID: $vid

    您需要将字符串与变量连接起来,它应该是:

    echo "ID: " . $vid;
    

    这将返回:ID: 2


    其次,您的查询将不起作用:

    $q = 'SELECT business_name, vd.ID_Vendor, res.ID_RestaurantEstablishment 
      FROM restaurant res
       INNER JOIN vendor_data vd
      ON vd.ID_Vendor=res.ID_Vendor AND res.ID_Vendor="$vid" ORDER BY business_name ASC';
    

    你应该用双引号将查询括起来,用单引号括起你的变量:

    $q = "SELECT business_name, vd.ID_Vendor, res.ID_RestaurantEstablishment 
      FROM restaurant res
       INNER JOIN vendor_data vd
      ON vd.ID_Vendor=res.ID_Vendor AND res.ID_Vendor='$vid' ORDER BY business_name ASC";
    

    【讨论】:

      【解决方案4】:

      对于 SQL,与 javascript 或 php 不同,string 或 char 只允许使用单引号。

      对于 MySQL,如果 res.id_vendor 的列类型是 number,res.id_vendor='1' 与 res.id_vendor=1 相同,所以最好总是用单引号包裹变量,如 res.id_vendor='$vid'

      最后,关于编码约定的cmets:建议不要在列命名中混合大小写字符,使用“_”作为单词分隔符,如

      vd.id_vendor
      res.id_restaurant_establishment
      

      【讨论】:

        猜你喜欢
        • 2013-06-26
        • 1970-01-01
        • 2016-09-12
        • 1970-01-01
        • 2014-10-22
        • 1970-01-01
        • 1970-01-01
        • 2012-12-03
        • 1970-01-01
        相关资源
        最近更新 更多