Detta verkar för mig vara en (n orapporterad?) bugg i PDO:s förberedda uttalandeemulering:
-
implementeringen av
PDOStatement::execute()så småningom anroparpdo_parse_params(); -
som i sin tur försöker att citera/escape värden baserat på den relevanta parameterns datatyp (som indikeras av
$data_typeargument tillPDOStatement::bindValue()ochPDOStatement::bindParam()—alla parametrar tillhandahålls som$input_parameterstillPDOStatement::execute()behandlas somPDO::PARAM_STR, som anges i dokumentationen för den funktionen); -
strängtypade värden escapes/citeras genom att anropar den relevanta databasdrivrutinens
quoter()metod oavsett om de ärnull:i fallet med PDO_MySQL är det mysql_handle_quoter() , som (så småningom) skickar värdet till antingen >mysqlnd_cset_escape_quotes()ellermysql_cset_escape_slashes(), beroende på servernsNO_BACKSLASH_ESCAPESSQL-läge; -
ges en
nullargument returnerar båda dessa funktioner en tom sträng.
Min åsikt är att innan du slår på parameterns typ
(i steg 2 ovan), pdo_parse_params() bör ställa in typen till PDO::PARAM_NULL om värdet är null . Vissa kanske menar att detta skulle förhindra typspecifik hantering av null värden där så är lämpligt, i vilket fall strängfallet (i steg 3 ovan) borde definitivt hantera null värden innan du fortsätter med ett anrop till förarens quoter() metod.
Som en tillfällig lösning är att inaktivera emulering av förberedda uttalanden vanligtvis det bästa ändå:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);