2011-09-24 172 views
37

我試圖在內容表中插入值。如果我在VALUES中沒有PHP變量,它工作正常。當我將變量$type置於VALUES中時,這不起作用。我究竟做錯了什麼?如何在MySQL插入語句中包含PHP變量

$type = 'testing'; 
mysql_query("INSERT INTO contents (type, reporter, description) VALUES($type, 'john', 'whatever')"); 

回答

62

添加字符串到查詢的規則很簡單明瞭:

  1. 該字符串應該用引號括起來。
  2. 因此,這些報價應在數據,以及一些其他字符轉義,使用mysql_real_escape_string()

所以,你的代碼變得

$type  = 'testing'; 
$type  = mysql_real_escape_string($type); 
$reporter = "John O'Hara"; 
$reporter = mysql_real_escape_string($reporter); 

$query = "INSERT INTO contents (type, reporter, description) 
      VALUES('$type', '$reporter', 'whatever')"; 
mysql_query($query) or trigger_error(mysql_error()." in ".$query); 
// note that when running mysql_query you have to always check for errors 

但是,如果你要添加變量在查詢的另一部分中,規則會改變。

  • 要添加一個數字,您必須明確地將其轉換爲其類型。

例如:

$limit = intval($_GET['limit']); //casting to int type! 
$query = "SELECT * FROM table LIMIT $limit"; 
  • 要添加一個標識符,這是更好地從某種白列表中進行選擇,包括硬編碼值

。例如:

if ($_GET['sortorder'] == 'name') { 
    $sortorder = 'name'; 
} else { 
    $sortorder = 'id'; 
} 
$query = "SELECT * FROM table ORDER BY $sortorder"; 

爲了使所有簡化的保證安全,必須使用某種類型的佔位符系統其中變量不是直接進入查詢,而是通過一些代理(稱爲佔位符)進入查詢。

所以,你的查詢電話變成這樣的事:

$type  = 'testing'; 
$reporter = "John O'Hara"; 
pquery("INSERT INTO contents (type, reporter, description) VALUES(?s, ?s, ?s)", 
     $type, $reporter,'whatever'); 

而且會有絕對沒有必要擔心所有這些問題。您可以使用PDO。雖然對於現實生活中的使用,您需要擴展套件,但只有少數庫提供,其中之一是SafeMysql

+0

什麼是'pquery()'? – Starx

+0

@Starx只是一個虛構的功能來展示這個想法。我知道沒有提供這樣的功能的圖書館。 –

+0

@YourCommonSense:Erm,任何PDO。 –

7

只要它是一個字符串 - 你必須把它放在引號

$type = 'testing'; 
mysql_query("INSERT INTO contents (type, reporter, description) VALUES('$type', 'john', 'whatever')"); 

而且,是內,爲達尼勸:你應該清理字符串你把查詢與mysql_real_escape_string()

+5

您應該警告您的代碼存在SQL注入危險。 – Dani

+1

你建議使用mysql_real_escape_string(),但在你的例子中你不這麼做... – AlxVallejo

+1

@AlxVallejo沒錯。 – zerkms

3

試試這個:

$type = 'testing'; 
mysql_query("INSERT INTO contents (type, reporter, description) VALUES('$type', 'john', 'whatever')"); 

你需要把'$type'不只是$型

3

$類型中的文本直接代入插入串,因此MySQL的得到這個:

... VALUES(testing, 'john', 'whatever') 

注意周圍有測試不包括引號,您需要把這些像這樣:

$type = 'testing'; 
mysql_query("INSERT INTO contents (type, reporter, description) VALUES('$type', 'john', 'whatever')"); 

我也建議你SQL injection讀了,因爲這種參數傳遞的是容易出現黑客攻擊,如果你不消毒所用的數據:

1

如果變量包含用戶輸入或你不能信任其他數據,一定要逃出數據。就像這樣:

$query = sprintf("INSERT INTO contents (type) VALUES ('%s')", mysql_real_escape_string($type)); 
$result = mysql_query($query); 
1

這裏

$type='testing' //it's string 

mysql_query("INSERT INTO contents (type, reporter, description) VALUES('$type', 'john', 'whatever')");//at that time u can use it(for string) 


$type=12 //it's integer 
mysql_query("INSERT INTO contents (type, reporter, description) VALUES($type, 'john', 'whatever')");//at that time u can use $type 
1

我知道這個問題有一些答案,但我想我會補充說,如果你按照下面的語法,我再也沒有遇到這個錯誤的問題。毫無疑問你正在使用哪張表以及你正在追加的列。

$query = "INSERT INTO contents (type, reporter, description) 
     VALUES('".$type."', '".$reporter."', '"$whatever."')"; 
2

這是最簡單的答案:

$query="SELECT * FROM CountryInfo WHERE Name = '".$name."'"; 

和定義任何你想要的$name
而另一種方式,在複雜的方式,就是這樣:

$query = " SELECT '" . $GLOBALS['Name'] . "' .* " . 
     " FROM CountryInfo " . 
     " INNER JOIN District " . 
     " ON District.CountryInfoId = CountryInfo.CountryInfoId " . 
     " INNER JOIN City " . 
     " ON City.DistrictId = District.DistrictId " . 
     " INNER JOIN '" . $GLOBALS['Name'] . "' " . 
     " ON '" . $GLOBALS['Name'] . "'.CityId = City.CityId " . 
     " WHERE CountryInfo.Name = '" . $GLOBALS['CountryName'] . 
     "'"; 
0

避免SQL注入插入語句是

$type = 'testing'; 

$stmt = $con->prepare("INSERT INTO contents (type, reporter, description) VALUES (?, ?, ?)"); 
     $stmt->bind_param("sss", $type , 'john', 'whatever'); 
     $stmt->execute(); 
    $stmt->close(); 
0

最好的辦法是準備好的語句。亂七八糟的報價和逃生是艱難的工作開始,並難以維持。遲早你會最終意外忘記引用某些東西,或者最終逃避同一個字符串兩次,或者搞砸了類似的東西。在找到這些類型的錯誤之前可能會有好幾年的時間。

http://php.net/manual/en/pdo.prepared-statements.php