【发布时间】:2012-11-27 11:02:04
【问题描述】:
我正在尝试将这些 mySQl INSERT INTO 和 Update 语句切换为 PDO 准备语句(主要是为了防止 SQL 注入),但我在正确使用语法时遇到了一些困难。
我目前使用 2 种类型的 INSERT/Update 语句:
声明 1 - 名称是硬编码的
$qry = "INSERT INTO customer_info(fname, lname, email, user_name, password)
VALUES('$_POST[fname]','$_POST[lname]','$_POST[email]','$user_name','".sha1($salt + $_POST['password'])."')";
$result = @mysql_query($qry)
语句 2 - 动态添加名称
大多数名称都是动态添加的,而不是列出每个元素的名称(名称被引用为 $fieldlist 或 $setlist,值是 $vallist)。唯一硬编码的名称/值是 user_id 或数组。我在下面包含了完整的代码。
$result = mysql_query('UPDATE fit_table SET '.$setlist.' WHERE user_id='.$user_id);
if (mysql_affected_rows()==0) {
$result = mysql_query('INSERT INTO fit_table ('.$fieldlist.') VALUES ('.$vallist.')'); };
这是我尝试过的:
声明 1 - 基于此帖子 https://stackoverflow.com/a/60530/1056713
$stmt = $conn->prepare("INSERT INTO customer_info VALUES(:fname, :lname, :email, :user_name, :password)");
$stmt->bindValue(':fname', $fname);
$stmt->bindValue(':lname', $lname);
$stmt->bindValue(':email', $email);
$stmt->bindValue(':user_name', $user_name);
$stmt->bindValue(':password ', $password);
$stmt->execute();
声明 2 - 基于此 PDO 包装器 https://github.com/Xeoncross/DByte/blob/master/DB.php(在此帖子中引用 https://stackoverflow.com/a/12500462/1056713)
static function insert($fit_table, array $fieldlist){
$query = "INSERT INTO`$fit_table`(`" . implode('`,`', array_keys('.$fieldlist.')). '`)
VALUES(' . rtrim(str_repeat('?,', count($fieldlist = array_values('.$vallist.'))), ',') . ')';
return DB::$p
? DB::column($query . 'RETURNING` user_id `', $fieldlist)
: (DB::query($query, $fieldlist) ? static::$c->lastInsertId() : NULL);
}
语句2的完整代码(这是目前动态添加名称的方式)
// INSERT
$fieldlist=$vallist='';
foreach ($_POST as $key => $value) {
if ($key=='pants_waistband'){$value= implode(',',$value);}
$fieldlist.=$key.',';
$vallist.='\''.($value).'\',';
}
$fieldlist=substr($fieldlist, 0, -1);
$vallist=substr($vallist, 0, -1);
$fieldlist.=', user_id';
$vallist.=','.$user_id;
// UPDATE
$setlist='';
foreach ($_POST as $key => $value) {
if ($key=='pants_waistband'){$value= implode(',',$value);}
$setlist.=$key .'=\''.$value.'\',';
}
$setlist=substr($setlist, 0, -1);
$result = mysql_query('UPDATE fit_table SET '.$setlist.' WHERE user_id='.$user_id);
if (mysql_affected_rows()==0) {
$result = mysql_query('INSERT INTO fit_table ('.$fieldlist.') VALUES ('.$vallist.')');}
【问题讨论】:
-
很高兴您正在进行过渡,但您的问题有点不清楚。你能告诉我们更多关于到底出了什么问题吗?
-
谢谢 :-) 我对 PDO 和 Prepared Statements 非常不熟悉,所以我确信问题在于我尝试将我的代码应用于我在网上找到的示例的方式。任何指导都会有所帮助,因为我发现 php.net 的手册有点过于技术化。
-
除了白名单之外,没有其他方法可以保护字段和表名。 没有例外。所以你必须保留允许的字段列表并且只将它们添加到查询中,而不是盲目地添加来自
$_POST的所有内容 -
@zerkms 谢谢!我逐渐意识到:-(
标签: php mysql pdo prepared-statement sql-injection