2011-09-24 119 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