Isso me parece ser um bug (n não relatado?) na emulação de instrução preparada do PDO:
-
a implementação dePDOStatement::execute()eventualmente invocapdo_parse_params();
-
que, por sua vez, tenta citar/escape valores com base no tipo de dados do parâmetro relevante (como indicado pelo$data_typeargumentos paraPDOStatement::bindValue()ePDOStatement::bindParam()—todos os parâmetros fornecidos como$input_parametersparaPDOStatement::execute()são tratados comoPDO::PARAM_STR, conforme indicado na documentação dessa função);
-
valores digitados em string são escapados/citados por chamando o driver de banco de dados relevantequoter()método independentemente de seremnull:no caso de PDO_MySQL, isso émysql_handle_quoter(), que (eventualmente) passa o valor paramysqlnd_cset_escape_quotes()oumysql_cset_escape_slashes(), dependendo doNO_BACKSLASH_ESCAPESdo servidor modo SQL;
-
dado umnullargumento, ambas as funções retornam uma string vazia.
Minha opinião é que, antes de ligar o parâmetro digite (no passo 2 acima),
pdo_parse_params() deve definir o tipo para PDO::PARAM_NULL se o valor for null . No entanto, alguns podem argumentar que isso impediria o tratamento específico do tipo de null valores quando apropriado, caso em que o caso de string (na etapa 3 acima) deve definitivamente lidar com null valores antes de continuar com uma chamada para quoter() do driver método. Como solução temporária, desabilitar a emulação de instrução preparada geralmente é o melhor:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);