pdo数据库抽象

时间:2009-11-13 19:16:31

标签: php syntax pdo

有人可以帮我看看这个设置出了什么问题

我在下面的函数中构建@sql查询,就像这样。 额外的引号在条件数组中设置。

        $sql .= " WHERE $field = \"$value\"";

pdo update函数循环条件数组。

if (!is_null($conditions))
{
$cond = ' WHERE';
$obj = new CachingIterator(new ArrayIterator($conditions));
foreach($obj as $k=>$v)
{
    $cond .= " $k=$v";
    $cond .= $obj->hasNext() ? ' AND' : '';
}
} 

我的观点是,我无法使用值构建数组,而不会在值周围添加引号的斜杠。 否则抛出的sql错误是它是一个未知的列。

还有其他我可以做的事吗?

请有人给我一些意见。

编辑:其余的关闭更新功能

我在哪里可以绑定条件数组的值并拥有它们 还执行了?正如我现在看到的那样,只执行values数组? 我是否需要循环两个数组然后合并两个数组?

$obj = new CachingIterator(new ArrayIterator($values));

            $db = db::getInstance();
            $sql = "UPDATE $table SET \n";
            foreach( $obj as $field=>$val)
            {
                $sql .= "$field= :$field";
                $sql .= $obj->hasNext() ? ',' : '';
                $sql .= "\n";
            }

            $sql .= $cond ; 
            $stmt = $db->prepare($sql);

            // bind de params
            foreach($values as $k=>$v)
            {
                $stmt->bindParam(':'.$k, $v);
            }


            $stmt->execute($values );
谢谢,理查德

2 个答案:

答案 0 :(得分:4)

如果您正在使用PDO,为什么不使用bindParam()bindValue()方法demonstated here

答案 1 :(得分:1)

请勿使用addslashes()。这是逃避价值观的不充分方法,并且已知安全漏洞。

标准SQL中的双引号用于分隔标识符。对单词引号使用单引号。

MySQL的默认模式允许您交替使用单引号和双引号,并为分隔标识符使用后引号。但我建议养成只使用单引号作为字符串的习惯,因为它使您的SQL代码对其他RDBMS供应商更具可移植性,并且对于阅读代码的任何人来说也更加清晰。

你应该使用查询参数,正如@Mike B建议的那样。这很容易,而且比将变量插入到SQL表达式中要安全得多。


您可以使用bindParam(),也可以为$values功能提供execute()关联数组。两者兼顾是多余的。

请注意,您为execute()方法提供的数组不必在占位符名称前加上:字符:

$stmt = $pdo->prepare("SELECT * FROM MyTable WHERE myfield = :myfield");
// both of the following would work:
$stmt->execute( array(":myfield" => $value ) );
$stmt->execute( array("myfield" => $value ) );

另外,为了支持SET子句和WHERE子句中的参数,我建议您在指定参数占位符名称时区分字段。这样,如果您在两个子句中引用相同的字段(一个用于搜索旧值,另一个用于设置新值),则不会发生冲突。

":set$field"子句中可能为SET":where$field"子句中可能为WHERE


更新:我测试了以下代码。首先,我使用普通数组,而不是您使用的CachingIterator。我不需要使用hasNext()方法,因为我正在使用join()

$settings = array("myfield" => "value");
$conditions = array("id" => 1);

$sql = "UPDATE $table SET \n";

接下来是使用array_map()join()代替循环的演示。我使用的是PHP 5.3.0,因此我可以使用内联闭包功能。如果您使用的是早期版本的PHP,则必须先声明这些函数并将它们用作回调函数。

$sql .= join(",",
    array_map(
        function($field) { return "$field = :set$field"; },
        array_keys($settings)
    )
);

if ($conditions)
{
    $sql .= " WHERE "
    . join(" AND ",
        array_map(
            function($field) { return "$field = :where$field"; },
            array_keys($conditions)
        )
    );
}

$stmt = $db->prepare($sql);

我无法使bindParam()工作,它总是在数组中添加值“1”而不是实际值。所以这里是准备关联数组并将其传递给execute()的代码:

$params = array();
foreach ($settings as $field=>$value) {
    $params[":set$field"] = $value;
}
foreach ($conditions as $field=>$value) {
    $params[":where$field"] = $value;
}

$stmt->execute($params);
相关问题