2011-06-20 63 views
1

我試圖圍繞在SQL中編寫查詢來解決問題,我在理解我找到的這個示例時遇到了一些困難。SQL查詢幫助困惑關於行情和連接

$q = "INSERT INTO `dbUsers` (`username`,`password`,`email`) " 
     ."VALUES ('".$_POST["username"]."', " 
     ."PASSWORD('".$_POST["password"]."'), " 
     ."'".$_POST["email"]."')"; 

我想我絆倒了雙引號,單引號和back-ticks的使用。我將這個陳述與W3網站上的例子進行了比較,並且我感到非常困惑,因爲它似乎更加複雜。你能向我解釋一下上述查詢中發生了什麼?感謝您的幫助!

$sql="INSERT INTO Persons (FirstName, LastName, Age) 
VALUES 
('$_POST[firstname]','$_POST[lastname]','$_POST[age]')"; 

回答

1

雙引號包圍將作爲查詢字符串一部分的字符串。每個雙引號部分之間的點是連接運算符。他們一起加入個人字符串。 您會注意到每個$ _POST []數組變量前都有一個雙引號和點,之後有一個點和雙引號。

例如「。$ _POST [」用戶名「]」

第一個雙引號結束前面的字符串部分。最後一個開始下一個字符串部分。兩點之間的所有內容都是POST變量。點是必要的原因是因爲「用戶名」周圍的引號。在你的W3版本中,他們並沒有在$ _POST []數組鍵字符串(例如$ _POST [firstname]而不是$ _POST [「firstname」]或$ _POST ['firstname'])中使用引號,所以他們不需要使用點和引號。

如果你想保持簡單,不要使用$ _POST []變量中的引號,你不必使用它們周圍的所有點和引號。

如果您嘗試使用不帶點和引號的版本1,則PHP解析器將失敗,您將看到一個錯誤。

+0

@Vecta我還應該補充一點,根據php.net,你總是在數組變量的[]括號內使用引號,儘管出錯的可能性可能很小。 [閱讀](http://php.net/manual/en/language.types.array.php#language.types.array.foo-bar)下的「爲什麼是$ foo [bar]錯誤」瞭解更多詳情。 –

5

雙引號用於定義構建您的$q字符串的元素。單引號標識內的您正在構建的SQL查詢,反引號用於在MySQL中轉義對象名稱。

+5

...在這種情況下,反引號是沒用的,因爲沒有任何轉義名稱是MySQL中的保留字。 –

1

反引號'是爲了逃避MySQL關鍵字(通常用於表和列名)。在插入的任何字符串周圍都需要單引號或雙引號。

請注意,您應該調用mysql_real_escape_string對任何連接到SQL查詢的字符串。否則,如果$_POST也包含引號,則可以打出引號。這可能會被用來允許在所謂的SQL injection攻擊中執行任意的SQL命令。

1

'back ticks`可選地用於引用mysql字段名稱,如果您不小心使用mysqls保留字中的一個來命名字段,則需要它們,否則您不需要它們。

當你在字段中輸入一個字符串時,你必須「引用它」。

整個陳述必須引用,但不能與上述2)衝突,因此使用「雙引號」。

非標量值(如數組)不會自動展開,因此您必須「退出」。和。 「回到」PHP來使用連接標記點來構建字符串。

1

如果您使用保留字作爲表/字段名稱,並且單引號在SQL中描述字符串文字,則反引號是MySQL僞像。雙引號是PHP中特定的和單獨的字符串。所以,下面的查詢將如下所示:

$sql="INSERT INTO Persons (FirstName, LastName, Age) 
VALUES 
('".$_POST["firstname"]."','".$_POST["lastname"]."','".$_POST["age"]."')"; 

一兩件事,筆者上面做的是還打破了PHP字符串轉換成單獨的字符串,可能以提高可讀性。 MySQL服務器不關心這一點。

1
  • 雙引號是PHP代碼的一部分,告訴它雙引號內的項是字符串。它們不是正在構建的SQL的一部分。
  • 單引號用於包圍結果SQL中的值。也就是說,你告訴數據庫這裏使用的值是「bob」。對於某些類型的值(整數,布爾等),你不需要單引號。對於許多其他人(varchar,日期等),你需要單引號。
  • 反引號執行的功能與單引號相同,只是它們用於表名,字段名等等,而不是圍繞實際值。他們使用時有問題的名字將不會被數據庫進行解釋正確的有,例如,如果你有一個字段中指定count, since that's a keyword in SQL. As noted elsewhere, the backticks aren't necessary in your example, but many people put them in all the time because it doesn't hurt to have them; as a safety net, kindof.

To give a visible, simpler example

$name = "bob"; 
$sql = "SELECT * FROM `mytable` WHERE `name` = '" . $name . "'"; 

This would result in the $sql變量爲

SELECT * FROM `mytable` WHERE `name` = 'bob' 

正如你可以看到,雙引號不是的一部分字符串..他們只是用來創建它。在生成的SQL中,反引號圍繞表/字段名稱,單引號圍繞實際值bob

作爲一個完整的附註,直接在創建的SQL中使用POST值是很危險的,因爲它允許SQL注入攻擊。值應該被轉義或應該使用參數化查詢。

1

在第一個查詢中實際上有很多不必要的東西。有考慮到最佳做法,但它可以重新寫成這樣:

$q = "INSERT INTO dbUsers (username, password, email) 
    VALUES ('".$_POST["username"]."', 
    PASSWORD('".$_POST["password"]."'), 
    '".$_POST["email"]."')"; 

第一件事:INSERT INTO dbUsers

  • 這一切正在做的是告訴我們,我們將什麼表我們數據進入。

(username, password, email)

  • 指定我們插入(爲了特定的)列

VALUES ('".$_POST["username"]."', PASSWORD('".$_POST["password"]."'), '".$_POST["email"]."')

  • 我們的價值觀要插入(依賴的順序上列),然後是一個終止分號。

如果您重新寫這個硬編碼的值,而不是串聯,它看起來像:

VALUES ('myUserName', PASSWORD('myPassword'), 'myEmail')

所有這一切都應該是自explanitory。每個值都包含在單引號(')中,因爲它們是字符串。然後通過MySQL函數PASSWORD傳遞密碼值,該密碼值爲了安全目的散列了密碼。