如何在MySQL插入语句中包含PHP变量

Pin*_*kie 48 php mysql sql string variables

我正在尝试在内容表中插入值.如果我在VALUES中没有PHP变量,它可以正常工作.当我将变量$type放在VALUES中时,这不起作用.我究竟做错了什么?

$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description) 
     VALUES($type, 'john', 'whatever')");
Run Code Online (Sandbox Code Playgroud)

You*_*nse 93

将字符串添加到查询中的规则简单明了:

  1. 该字符串应用引号括起来.
  2. 因此,这些引号应该在数据中以及其他一些字符中使用 mysqli

所以,你的代码就变成了

$type = 'testing';
$reporter = "John O'Hara";
$query = "INSERT INTO contents (type, reporter, description) 
             VALUES(?, ?, 'whatever')";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("ss", $type, $reporter);
$stmt->execute();
Run Code Online (Sandbox Code Playgroud)

但是,如果您要在查询的另一部分中添加变量,则规则会发生变化.

  • 要添加数字,必须明确地将其强制转换为类型.

例如:

$type = 'testing';
$reporter = "John O'Hara";
$query = "INSERT INTO contents (type, reporter, description) 
             VALUES(?, ?, 'whatever')";
$stmt = $pdo->prepare($query);
$stmt->execute([$type, $reporter]);
Run Code Online (Sandbox Code Playgroud)
  • 要添加标识符,最好从某种白名单中选择它,由硬编码值组成

例如:

$orderby = $_GET['orderby'] ?: "name"; // set the default value
$allowed = ["name","price","qty"]; // the white list of allowed field names
$key = array_search($orderby, $allowed, true); // see if we have such a name
if ($key === false) { 
    throw new InvalidArgumentException("Invalid field name"); 
}
Run Code Online (Sandbox Code Playgroud)

为了使所有这些都得到简化而且保证安全,必须使用某种占位符系统,其中变量不是直接进入查询,而是通过一些称为占位符的代理.

所以,你的查询调用变成这样的:

$direction = $_GET['direction'] ?: "ASC";
$allowed = ["ASC","DESC"];
$key = array_search($direction, $allowed, true);
if ($key === false) { 
    throw new InvalidArgumentException("Invalid ORDER BY direction"); 
}
Run Code Online (Sandbox Code Playgroud)

而且绝对没有必要担心所有这些问题.

对于有限的占位符集,您可以使用PDO.虽然对于现实生活中的使用,您将需要扩展集,但由一些库提供,其中一个是SafeMysql.


小智 10

为避免 SQL 注入,插入语句为

$type = 'testing';
$name = 'john';
$description = 'whatever';

$con = new mysqli($user, $pass, $db);
$stmt = $con->prepare("INSERT INTO contents (type, reporter, description) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $type , $name, $description);
$stmt->execute();
Run Code Online (Sandbox Code Playgroud)


zer*_*kms 7

只要它是一个字符串 - 你必须把它放在引号内

$type = 'testing';
mysql_query("INSERT INTO contents (type, reporter, description) VALUES('$type', 'john', 'whatever')");
Run Code Online (Sandbox Code Playgroud)

而且,是的,正如Dani所说:你应该清理你在查询中放入的每个字符串mysql_real_escape_string()

  • 您应警告您的代码具有SQL注入危险. (6认同)
  • 您建议使用mysql_real_escape_string(),但在您的示例中则不要这样做。 (2认同)