2015-05-03 19 views
0

我有一個表單接受幾個名稱和電話號碼,並將它們發佈到PHP腳本,然後將這些值插入到MySQL表中。代碼(PHP)是非常簡單的,你可以在這裏看到:如何在MySQL的表單字段中接受撇號

$sql = "INSERT INTO Contact_table (PHONE, NAME) VALUES "; 
for ($i = 0; $i < $arr; ++$i){ 
    $sql .= "('".$numbers[$i]."', '".$names[$i]."'),"; 
} 
$sql = substr($sql, 0, -1)." ON DUPLICATE KEY UPDATE name = COALESCE(VALUES(name), name);"; 
$connect = dbconn(PROJHOST,PROJDB,PROJDBUSER,PROJDBPWD); 

$query = $connect->query($sql); 
$connect = NULL; 

這完美的作品,除了它拒絕接受像奧哈拉或杜澤任何名稱。我隱約意識到PDO準備好的聲明在這種情況下有一些用處,但我無法使其工作。我試過是這樣的:

$query = $connect->prepare($sql); 
$query->execute(); 

取而代之的是:

$query = $connect->query($sql); 

任何提示?我錯過了什麼?

+3

不僅你的代碼不會像奧哈拉名工作,但它是一個巨大的安全漏洞,以及,是容易受到SQL注入。只需按照這裏的建議... http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers。 – zgguy

+0

這就是確切的原因(當然也包括撇號問題)我非常喜歡使用準備好的語句,但它沒有幫助,因此在這裏。 – TheLearner

+2

準備一個帶硬編碼參數值的SQL語句毫無意義...您需要像$ stmt = $ connect-> prepare('INSERT INTO Contact_table(PHONE,NAME)VALUES(?,?)ON DUPLICATE KEY UPDATE name = COALESCE(VALUES(name),name)');在循環之前,然後在循環中:$ stmt-> execute(array($ numbers [$ i],$ names [$ i])); – zgguy

回答

1

有幾種方法可以解決您的問題。你可以使用real_escape_string來避開你的字符串,因爲你建議更好的方法。最好的一種是通過使用mysqli或PDO的準備語句。

既然你提到PDO,這是一個很好的方法,這裏是如何處理這樣說:

的第一件事涉及貫穿trycatch,然後連接您用佔位符您的查詢,然後綁定你的變量到這些佔位符。下面是它如何工作的一個簡單的方法:

try { 
$connect = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); 
$stmt = $conn->prepare("INSERT INTO Contact_table (PHONE, NAME) VALUES (:PHONE, :NAME)"); 
$stmt->bindParam(':PHONE', $PHONE); 
$stmt->bindParam(':NAME', $NAME); 
//then name your variables like so 
$PHONE = [whatever your phone number variable(s) is/are equal to]; 
$NAME = [whatever the NAME variable(s) is/are equal to]; 
$stmt->execute(); 
//note the last section can occur within a loop, much like you have above. 
catch(PDOException $error) 
} 
{ 
echo "Error: " . $error->getMessage(); 
} 
$connect = null; 
} 

注意,這不僅會允許有特殊字符,如撇號的任何字段,它會運行得更快的大型查詢,並有被很多額外的獎勵更安全,因爲它幾乎消除了大多數SQL注入方法。

您也可以通過mysqli準備好的語句來完成此任務,但PDO還具有與數據庫無關的附加優勢,因爲可以輕鬆連接到MySQL以外的數據庫。

此外,您可以使用?方法對其中一個註釋中提到的鬆散定義的參數使用方法,但這也有助於將它們作爲對象進行操作。

這裏有一個很好的參考,如果你想了解更多:PHP Prepared Statements

+0

感謝您的詳細解釋。但是這仍然不能解決我的問題,因爲我正在使用構建在循環中的單個INSERT查詢插入多個事件(實際上是一大堆)。如果我使用prepare-bind方法(我真的很想),我無法將查詢保留爲單個實體,因爲execute()函數在循環的每次迭代中都必須運行一次。這可能會導致我想避免的很多查詢。有沒有什麼辦法可以在保留我的原始代碼中的單一查詢目標的同時使用prepare-bind? – TheLearner

+0

是的,任何時候你調用一個變量,你都可以用綁定的參數替換它。例如'$ numbers [$ i]'和'$ names [$ i]'可以轉換成參數,在調用它之前將其轉換爲更乾淨的變量是一個好主意。你也不應該需要多個參數。你總是可以在'try'中運行一個循環來獲得多個值。您可以輸入的數量也沒有限制。只需在循環中通過'$ stmt-> execute();'運行每個變量迭代,它就會正常運行。這是關於準備好的陳述的最好的事情之一; – nomistic

+0

爲了縮短這一點,您只需要一個查詢。您可以在執行查詢之前使用'while'或'foreach'循環獲取其他項目。 – nomistic