PDO PHP从关联数组插入到DB中

Fox*_*Fox 9 php mysql database arrays pdo

我有这样的数组

  $a = array( 'phone' => 111111111, 'image' => "sadasdasd43eadasdad" );
Run Code Online (Sandbox Code Playgroud)

当我进行var-dump时,我得到了这个 - >

 { ["phone"]=> int(111111111) ["image"]=> string(19) "sadasdasd43eadasdad" }
Run Code Online (Sandbox Code Playgroud)

现在我尝试使用IN语句将其添加到数据库 -

 $q = $DBH->prepare("INSERT INTO user :column_string VALUES :value_string");
 $q->bindParam(':column_string',implode(',',array_keys($a)));
 $q->bindParam(':value_string',implode(',',array_values($a)));
 $q->execute();
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是implode返回一个字符串.但'phone'列是数据库中的整数,并且数组也将其存储为整数.因此我收到SQL错误,因为我的最终查询看起来像这样 -

INSERT INTO user 'phone,image' values '111111111,sadasdasd43eadasdad';
Run Code Online (Sandbox Code Playgroud)

哪个是错误的查询.有没有办法解决它.

我的列名是动态的,基于用户想要插入的内容.所以我不能使用像:phone:image这样的占位符,因为我可能并不总是得到这两列的值.如果有办法,请告诉我.否则我将不得不为每种类型的更新定义多个功能.

谢谢.

Mor*_*kel 10

上次我检查时,不可能准备一份声明,其中受影响的列在准备时是未知的 - 但这似乎有用 - 也许你的数据库系统比我使用的更宽容(主要是postgres)

显而易见的是implode()语句,因为每个变量都应该由它自己处理,你还需要在insert语句中的字段列表周围加括号.

要插入用户定义的字段,我认为你必须做这样的事情(至少我是怎么做的);

$fields=array_keys($a); // here you have to trust your field names! 
$values=array_values($a);
$fieldlist=implode(',',$fields); 
$qs=str_repeat("?,",count($fields)-1);
$sql="insert into user($fieldlist) values(${qs}?)";
$q=$DBH->prepare($sql);
$q->execute($values);
Run Code Online (Sandbox Code Playgroud)

如果你不相信$ a中的字段名称,你必须做类似的事情

foreach($a as $f=>$v){
   if(validfield($f)){
      $fields[]=$f;
      $values[]=$v;
   }
}
Run Code Online (Sandbox Code Playgroud)

validfields是你编写的函数,它测试每个fieldname并检查它是否有效(通过建立一个关联数组来快速和脏化$ valfields = array('name'=> 1,'email'=> 1,'phone'= > 1 ...然后通过从服务器获取字段名称来检查$ valfields [$ f]的值,或者(我希望如此)

  • **SQL INJECTION**如果您的表单填写了`$ a`,这是不安全的.它在文中,但我觉得这需要更加明显.如果您需要用户输入,请使用过滤器:http://stackoverflow.com/a/4260168/956397 (3认同)

Bil*_*win 6

SQL查询参数只能用于放置文字值的位置.

因此,如果您可以看到自己在查询中的该位置放置带引号的字符串文字,日期文字或数字文字,则可以使用参数.

您不能将参数用于列名,表名,值列表,SQL关键字或任何其他表达式或语法.

对于这些情况,您仍然需要将内容插入到SQL字符串中,因此您有一些SQL注入的风险.防止这种情况的方法是将列名列入白名单,并拒绝任何与白名单不匹配的输入.


PiT*_*ber 5

因为所有其他答案都允许SQL 注入。对于用户输入,您需要过滤允许的字段名称:

// change this
$fields = array('email', 'name', 'whatever');
$fieldlist = implode(',', $fields);
$values = array_values(array_intersect_key($_POST, array_flip($fields)));
$qs = str_repeat("?,",count($fields)-1) . '?';
$q = $db->prepare("INSERT INTO events ($fieldlist) values($qs)");
$q->execute($values);
Run Code Online (Sandbox Code Playgroud)