Il tuo PDO è configurato per emulare le query preparate, mentre mysqli utilizza vere query preparate.
La query preparata associa la stringa ''1''
come valore di parametro intero. PHP lo costringe a un numero intero usando qualcosa come intval()
. Qualsiasi stringa con caratteri iniziali non numerici viene interpretata come 0 da PHP, quindi il valore del parametro inviato dopo preparare è il valore 0.
La falsa query preparata utilizza interpolazione di stringhe (anziché vincolare) per aggiungere la stringa ''1''
nella query SQL prima MySQL lo analizza. Ma il risultato è simile, perché SQL tratta anche una stringa con caratteri iniziali non numerici in un contesto intero come valore 0.
L'unica differenza è ciò che finisce nel registro della query generale quando il parametro è associato prima della preparazione rispetto a dopo la preparazione.
Puoi anche fare in modo che PDO utilizzi query preparate reali, quindi dovrebbe agire proprio come mysqli in questo caso:
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
PS:questo potrebbe dimostrare una buona ragione per cui è consuetudine iniziare i valori id da 1 anziché da 0.