Förra gången jag kollade var det inte möjligt att förbereda ett uttalande där de berörda kolumnerna var okända vid förberedelsetiden - men den saken verkar fungera - ditt databassystem kanske är mer förlåtande än de jag använder (främst postgres)
Det som är uppenbart fel är implode()-satsen, eftersom varje variabel ska hanteras av sig själv behöver du också ha en parentes runt fältlistan i insert-satsen.
För att infoga användardefinierade fält tror jag att du måste göra något sånt här (åtminstone så här gör jag);
$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);
Om du inte kan lita på fältnamnen i $a måste du göra något liknande
foreach($a as $f=>$v){
if(validfield($f)){
$fields[]=$f;
$values[]=$v;
}
}
Där validfields är en funktion som du skriver som testar varje fältnamn och kontrollerar om det är giltigt (snabbt och smutsigt genom att göra en associativ array $valfields=array('name'=>1,'email'=>1, 'phone'=>1 ... och sedan kontrollera efter värdet på $valfields[$f], eller (som jag skulle föredra) genom att hämta fältnamnen från servern)