Problemet her er, at du binder parametre med bindParam , som bruger binding ved reference. I dit tilfælde skal du bruge bindValue i stedet:
foreach( $binders as $key => $value ) {
$sql->bindValue( $key, $value );
}
Eller du kan sende dit array direkte til execute() metode:
$sql->execute( $binders );
Som beskrevet i manualen:
the variable is bound as a reference and will only be evaluated at the time that PDOStatement::execute() is called.
Så når din foreach loop slutter $value har værdien af sidste matrixelement Apple . Så når execute kører, både :ctid og :p1 værdier bliver lig med Apple . Det er bestemt ikke, hvad du ønsker)