Problemet här är att du binder parametrar med bindParam , som använder bindning genom referens. I ditt fall bör du använda bindValue istället:
foreach( $binders as $key => $value ) {
$sql->bindValue( $key, $value );
}
Eller så kan du skicka din array direkt till execute() metod:
$sql->execute( $binders );
Som beskrivs 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 slutar $value har värdet för sista matrisobjektet Apple . Så när execute körs, båda :ctid och :p1 värden blir lika med Apple . Visst, detta är inte vad du vill)