This seems to be a bug in PDO. If I try
$stmt = $pdo->prepare('
UPDATE Guests SET
`Profile is Subscribed ?` = :subscribed,
`Private ?` = :private
WHERE intID = 123
');
$stmt->execute(['subscribed' => 1, 'private' => 0]);
I get this error:
PDOException: SQLSTATE[HY093]: Invalid parameter number: mixed named
and positional parameters in ...
As a workaround: Don't use named placeholders. Use ? instead. But then you need to bind the values in correct order:
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$stmt = $pdo->prepare('
UPDATE Guests SET
`Profile is Subscribed ?` = ?,
`Private ?` = ?
WHERE intID = 123
');
$stmt->execute([1,0]);
It's important, that you set ATTR_EMULATE_PREPARES to false. Otherwise you will get another error:
PDOException: SQLSTATE[HY093]: Invalid parameter number: number of
bound variables does not match number of tokens in ...
Another workaround is to use the SQL mode ANSI_QUOTES:
$pdo->exec("SET SESSION sql_mode = concat(@@sql_mode, ',ANSI_QUOTES')");
$stmt = $pdo->prepare('
UPDATE Guests SET
"Profile is Subscribed ?" = :subscribed,
"Private ?" = :private
WHERE intID = 123
');
$stmt->execute(['subscribed' => 1, 'private' => 0]);
But personally - I would rather rename the column names.