2013-08-17 22 views
-3

這是參數化之前的sql查詢。我試圖參數化代碼,以防止SQL注入攻擊。班斯幫助我解決了這個問題。他的答案在下面打勾一個示例顯示如何參數化sql查詢以防止sql注入攻擊

下面的代碼就是我們要參數化的東西。

$sqlCommand = "(SELECT * FROM products WHERE product_name LIKE '%$searchquery%' OR details LIKE '%$searchquery%' OR category LIKE '%searchquery%' OR subcategory LIKE '%searchquery%' OR price LIKE '%searchquery%') "; 
} 
require_once("storescripts/connect_to_mysqli.php"); 
$query = mysqli_query($myConnection,$sqlCommand) or die(mysqli_error($myConnection)); 
$count = mysqli_num_rows($query); 
if($count >= 1){ 
    $search_output .= "<hr />$count results for <strong>$searchquery</strong><hr />"; 
    while($row = mysqli_fetch_array($query)){ 

它應該根據bansi回答改爲下面的代碼。關鍵部分如下

require_once ("storescripts/connect_to_mysqli.php"); 
$stmt = $myConnection->prepare('SELECT id, product_name, price FROM products WHERE product_name LIKE ? OR details LIKE ? OR category LIKE ? OR subcategory LIKE ? OR price LIKE ?'); 
$param = "%$searchquery%"; 
$stmt->bind_param('sssss', $param, $param, $param, $param, $param); 
$stmt->execute(); 
/* store result */ 
$stmt->store_result(); 
/* get the row count */ 
$count = $stmt->num_rows; 
if ($count >= 1) { 
    $search_output = "<hr />$count results for <strong>$searchquery</strong><hr />"; 
    $stmt->bind_result($id, $product_name, $price); 

    while ($stmt->fetch()) { 
     printf("%s %s %s\n", $id, $product_name, $price); 
+0

看起來你需要正確地逃脫你的報價(或使用雙打)。 ''''''或'''「'另外,這應該是你首先應該谷歌的東西。我可以肯定地說,第一個SERP上的某個人詢問了你確切的問題。 –

+0

這與數據庫代碼或預處理語句無關。這是錯誤的字符串。無論如何,佔位符並不屬於單引號。 – mario

+0

請使用好的IDE /編輯器。使您的編碼更容易。 – bansi

回答

1

下面的代碼工作並給出結果,但它不能正確顯示結果 如何修改$ search_output?

<?php 

$search_output = ""; 

if (isset($_POST['searchquery']) && $_POST['searchquery'] != "") { 
    $searchquery = preg_replace('/[^a-zA-Z0-9_ %\[\]\/\.\(\)%&-]/s', '', $_POST['searchquery']); 
    if ($_POST['filter1'] == "Products") { 
     require_once ("storescripts/connect_to_mysqli.php"); 
     //syntax error string not quoted properly 
     $stmt = $myConnection->prepare('SELECT * FROM products WHERE product_name LIKE ? OR details LIKE ? OR category LIKE ? OR subcategory LIKE ? OR price LIKE ?'); 
     $param = "%$searchquery%"; 
     $stmt->bind_param('sssss', $param , $param , $param , $param , $param); 
     $stmt->execute(); 
     $stmt->bind_result($id, $product_name, $price); 

     while ($stmt->fetch()) { 
      printf("%s %s %s\n", $id, $product_name, $price); 
      $search_output .= " 
      <li><div class='product'> 
      <a href='product.php?id=$id' class='info'> 
      <span class='holder'> 
      <img src='inventory_images/$id.jpg' alt='$product_name' /> 
      <span class='book-name'>$product_name</span> 
      </a> 
      <a href='product.php?id=$id' class='buy-btn'>RM<span class='price'>$price</span></a> 
      </div> 
      </li> 

      "; 
     }//While loop was not closed 

    } else { 
     $search_output = "<hr />0 results for <strong>$searchquery</strong><hr />"; 
    } 
} 
?> 

您有2個語法錯誤。 編輯以解決綁定語句和SQL改變

<?php 

$search_output = ""; 

if (isset($_POST['searchquery']) && $_POST['searchquery'] != "") { 
    $searchquery = preg_replace('/[^a-zA-Z0-9_ %\[\]\/\.\(\)%&-]/s', '', $_POST['searchquery']); 
    if ($_POST['filter1'] == "Products") { 
     require_once ("storescripts/connect_to_mysqli.php"); 
     //syntax error string not quoted properly 
     $stmt = $myConnection->prepare('SELECT * FROM products WHERE product_name LIKE ? OR details LIKE ? OR category LIKE ? OR subcategory LIKE ? OR price LIKE ?'); 
     $param = "%$searchquery%"; 
     $stmt->bind_param('sssss', $param , $param , $param , $param , $param); 
     $stmt->execute(); 
     $stmt->bind_result($product_name, $price); 

     while ($stmt->fetch()) { 
      printf("%s %s\n", $product_name, $price, $totalpoints); 

      $search_output .= " 
      <li><div class='product'> 
      <a href='product.php?id=$id' class='info'> 
      <span class='holder'> 
      <img src='inventory_images/$id.jpg' alt='$product_name' /> 
      <span class='book-name'>$product_name</span> 
      </a> 
      <a href='product.php?id=$id' class='buy-btn'>RM<span class='price'>$price</span></a> 
      </div> 
      </li> 

      "; 
     }//While loop was not closed 

    } else { 
     $search_output = "<hr />0 results for <strong>$searchquery</strong><hr />"; 
    } 
} 
?> 

還需要綁定的所有5個參數更改以下行。

$stmt->bind_param('s', '%$searchquery%'); 

編輯:

$stmt->bind_result($product_name, $price); 

應爲下列如果第三列總積分。這是不可能的,當你使用*select

$stmt->bind_result($product_name, $price, $totalpoints); 

而且

printf("%s %s\n", $product_name, $price, $totalpoints); 

可以

printf("%s %s %s\n", $product_name, $price, $totalpoints); 

或只是

echo "$product_name $price $totalpoints\n"; 

知道列名在執行語句後獲得總體使用。

$count = $stmt->num_rows; 

編輯2 檢查,如果這個工程增加數也。

$search_output = ""; 

if (isset($_POST['searchquery']) && $_POST['searchquery'] != "") { 
    $searchquery = preg_replace('/[^a-zA-Z0-9_ %\[\]\/\.\(\)%&-]/s', '', $_POST['searchquery']); 
    if ($_POST['filter1'] == "Products") { 
     require_once ("storescripts/connect_to_mysqli.php"); 
     $stmt = $myConnection->prepare('SELECT id, product_name, price FROM products WHERE product_name LIKE ? OR details LIKE ? OR category LIKE ? OR subcategory LIKE ? OR price LIKE ?'); 
     $param = "%$searchquery%"; 
     $stmt->bind_param('sssss', $param, $param, $param, $param, $param); 
     $stmt->execute(); 
     /* store result */ 
     $stmt->store_result(); 
     /* get the row count */ 
     $count = $stmt->num_rows; 
     if ($count >= 1) { 
      $search_output = "<hr />$count results for <strong>$searchquery</strong><hr />"; 
      $stmt->bind_result($id, $product_name, $price); 

      while ($stmt->fetch()) { 
       printf("%s %s %s\n", $id, $product_name, $price); 
       $search_output .= " 
       <li><div class='product'> 
       <a href='product.php?id=$id' class='info'> 
       <span class='holder'> 
       <img src='inventory_images/$id.jpg' alt='$product_name' /> 
       <span class='book-name'>$product_name</span> 
       </a> 
       <a href='product.php?id=$id' class='buy-btn'>RM<span class='price'>$price</span></a> 
       </div> 
       </li> 

       "; 
      } 
     } else { 
      $search_output = "<hr />0 results for <strong>$searchquery</strong><hr />"; 
     } 

    } else { 
     $search_output = "<hr />0 results for <strong>$searchquery</strong><hr />"; 
    } 
} 
+0

您的解決方案說致命錯誤:無法通過參考傳遞參數2也要感謝 –

+1

您應該更改綁定行。請參閱@ DevZer0的答案 – bansi

+0

改變了但仍然沒有運氣? –

2

問題出在你準備好的聲明中。 正確的做法是在引號周圍省略單引號。如果您需要在引號內使用引號,則可以在單引號內使用雙引號。

這裏是解決方案:的生成類似字符串連接字符串一起當

$stmt = $myConnection->prepare('SELECT * FROM products WHERE product_name LIKE ? OR details LIKE ? OR category LIKE ? OR subcategory LIKE ? OR price LIKE ? ');

另一種選擇。像這樣:

$string = $oldString. " hello";

1

你的第一個問題是你沒有正確地參數化你的查詢。您過早地終止了您的字符串,並從語言解釋程序的上下文中插入了一個?。這顯然會導致語法錯誤。

在不中斷字符串的情況下插入參數。

->prepare('SELECT * FROM products WHERE product_name LIKE ? OR details LIKE ? OR category` LIKE ? OR subcategory LIKE ? OR price LIKE ?'); 

現在你有5個參數。您需要爲所有5個參數提供值,如下所示。

$stmt->bind_param('sssss', "%$searchquery%", "%$searchquery%", "%$searchquery%", "%$searchquery%", "%$searchquery%"); 

我還注意到,您曾經在您的%$searchquery%變量使用單引號(')。您將需要使用雙引號",因爲單引號不會擴展您的變量。

+0

我可以知道「」和「'的區別嗎? –

+1

如果你使用'''(單個)引用一個字符串,你放入的所有內容都將被視爲文字字符串。但如果你使用''''(雙)php將嘗試解析字符串內的所有變量,並用變量的值替換。 – bansi

+0

erm ..我想我現在有些感覺..很高興 –