我有一个HTML
textarea
元素的输入值无法插入MySQL表,因为它包含撇号(')字符,例如:'Adam's garden'
。所以我使用了PHP文档建议的PDO :: prepare()函数,但我仍然无法将这些数据插入到表中,但是当我删除撇号来获取'Adams garden'
时,该值成功插入< / p>
我认为PDO::prepare()
函数应该处理引号并转义SQL语句的特殊字符。 PHP文档确实说使用PDO::prepare()
绑定参数,但我没有将我的php变量绑定到查询参数。绑定参数是绝对必要的还是只是说明,因为这是使用PDO::prepare()
函数的常用方法?
我如何引用和转义输入变量中的特殊字符?
修改
我正在使用字符串连接来执行多个SQL INSERT
。撇号位于下面示例代码的$evData['Description']
字段中。
$evQuery ="INSERT INTO ep_events
VALUES(NULL, '" .$evData['Title'] ."', '" .$evData['Venue'] ."', '" .$evData['Address'] ."', '" .$evData['Description'] ."')";
$tkQuery ="INSERT INTO ep_tickets VALUES";
foreach ($tkData as $ref =>$tkObj){
for($i=0; $i<$tkObj['Quantity']; $i++){
$tkQuery .='(NULL, LAST_INSERT_ID(), "' .$tkObj['Name'] .'", "' .$tkObj['Price'] .'"),';
}
}
$tkQuery =rtrim($tkQuery, ',');
$query ='START TRANSACTION;' .$evQuery ."; " .$tkQuery .';' .'COMMIT;';
$stm =$db->prepare($query);
$stm->execute();
这是PHP文档部分:
PDO :: quote()在输入字符串周围放置引号(如果需要),并使用适合于基础&gt;驱动程序的引用样式转义输入字符串中的特殊&gt;字符。
如果您正在使用此函数来构建SQL语句,那么您就是 强烈建议使用PDO :: prepare()来准备SQL语句 使用绑定参数而不是使用PDO :: quote()进行插值 用户输入到SQL语句中。带有约束的预备语句 参数不仅更便携,更方便,不受SQL的影响 注入,但通常比插值快得多 查询,因为服务器端和客户端都可以缓存已编译的表单 的查询。 http://www.php.net/manual/en/pdo.quote.php
答案 0 :(得分:6)
PDO::prepare
仅创建预备语句。查询必须正确参数化,您必须将参数发送到execute
(或以其他方式绑定它们)才能正确转义。例如:
$ta = $_REQUEST['textarea'];
$stmt = $pdo->prepare("INSERT INTO t1 VALUES (?)");
$stmt->execute(array($ta));
你可能正在做的是
$pdo->prepare("INSERT INTO t1 VALUES ('" . $_REQUEST['ta'] . "')")->execute();
在这种情况下输入不会被转义。
答案 1 :(得分:0)
SQL语句是代码。当您使用串联(或其他)构建SQL查询时,您正在进行代码生成。当您生成PHP代码(eval ("echo '$variable';");
)或HTML代码(<h1><?= $header?></h1>
)时,此代码生成具有相同的问题。生成的代码中没有“数据”,只有代码本身。
有几种方法可以尝试避免不必要的行为。
打包/解包:使用base64_encode / FROM_BASE64作为数据库的数据变量,使用base64_encode / base64_decode作为eval,使用htmlentities作为html。
转义:$ PDO :: quote()用于数据库的数据变量,某些函数用于eval(例如return '\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $var) . '\'';
)
(坏)删除'危险'构造:(例如`$ v = preg_replace('/ UNION(?:\ s + ALL)?\ s + SELECT / i',' - ',$ a);)用于数据库,用于HTML的strip_tags。
从代码中分离数据:为数据库准备语句,生成函数并将数据传递给它以进行评估,使用文档对象模型构建HTML。
因此,预准备语句的主要思想是从代码中分离数据。因此,您必须直接指定数据的位置和代码的位置。
使用预准备语句插入的最简单方法是
$pdo->prepare('INSERT INTO `table` (`text`) VALUES(?);')->execute(array($text));
请记住,准备好的陈述是避免麻烦的首选方式。如果你可以使用预备语句 - 使用它。