1

HTML textarea我有来自无法插入 MySQL 表的元素的输入值,因为它包含撇号(')字符,例如: 'Adam's garden'。因此,我按照 PHP 文档的建议使用了 PDO::prepare() 函数,但我仍然无法将此数据插入表中,但是当我删除撇号时'Adams garden',该值已成功插入

我认为该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() 在输入字符串周围放置引号(如果需要)并转义输入字符串中的特殊 > 字符,使用适合底层 > 驱动程序的引用样式。

如果您使用此函数构建 SQL 语句,强烈建议您使用 PDO::prepare() 来准备带有绑定参数的 SQL 语句,而不是使用 PDO::quote() 将用户输入插入到 SQL 语句中。带有绑定参数的预处理语句不仅更便携、更方便、不受 SQL 注入的影响,而且执行起来通常比插值查询快得多,因为服务器端和客户端都可以缓存查询的编译形式。 http://www.php.net/manual/en/pdo.quote.php

4

2 回答 2

7

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();

在这种情况下,输入不会被转义。

于 2013-06-25T23:37:16.190 回答
0

SQL 语句就是代码。当您使用连接(或其他方式)构建 SQL 查询时,您正在生成代码。当您生成 php 代码 ( eval ("echo '$variable';");) 或 HTML 代码 ( <h1><?= $header?></h1>) 时,此代码生成也存在同样的问题。生成的代码中没有“数据”,只有代码本身。

有几种方法可以避免不必要的行为。

  1. 打包/解包:数据库使用base64_encode/FROM_BASE64作为数据变量,eval使用base64_encode/base64_decode,html使用htmlentities。

  2. 转义:$PDO::quote() 用于数据库的数据变量,用于 eval 的某些函数(例如return '\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $var) . '\'';

  3. (坏)删除“危险”结构:(例如 `$v = preg_replace('/UNION(?:\s+ALL)?\s+SELECT/i', '--', $a);) 用于数据库, 用于 HTML 的 strip_tags。

  4. 从代码中分离数据:为数据库准备语句,生成函数并将数据传递给它以进行评估,使用文档对象模型构建 HTML。

因此,准备好的语句的主要思想是从代码中分离数据。因此,您必须直接指定数据在哪里以及代码在哪里。

使用准备好的语句插入的最简单方法是

$pdo->prepare('INSERT INTO `table` (`text`) VALUES(?);')->execute(array($text));

请记住,准备好的语句是避免麻烦的首选方法。如果你可以使用准备好的语句——使用它。

于 2013-06-26T01:28:36.760 回答