Le problème ici est que vous liez les paramètres avec bindParam , qui utilise la liaison par référence. Dans votre cas, vous devez utiliser bindValue à la place :
foreach( $binders as $key => $value ) {
$sql->bindValue( $key, $value );
}
Ou vous pouvez passer votre tableau directement à execute() méthode :
$sql->execute( $binders );
Comme décrit dans le manuel :
the variable is bound as a reference and will only be evaluated at the time that PDOStatement::execute() is called.
Ainsi, lorsque votre boucle foreach se termine $value a la valeur du dernier élément du tableau Apple . Ainsi, lorsque execute s'exécute, à la fois :ctid et :p1 les valeurs deviennent égales à Apple . Ce n'est sûrement pas ce que vous voulez)