有人可以帮我看看这个设置出了什么问题
我在下面的函数中构建@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 );
谢谢,理查德
答案 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);