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_type
argument tillPDOStatement::bindValue()
ochPDOStatement::bindParam()
—alla parametrar tillhandahålls som$input_parameters
tillPDOStatement::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_ESCAPES
SQL-läge; -
ges en
null
argument 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);