Поскольку вы используете PDO, а не mysqli интерфейс, вам нужно использовать именованные параметры в запросе SQL, как показано здесь: https://www.php.net/manual/en/pdo.prepare.php
В настоящее время вы полагаетесь на bind_param, который является методом дляИнтерфейс mysqli.
На основе документов PDO:
<?php
/* Execute a prepared statement by passing an array of values */
$sql = 'SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour';
$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(':calories' => 150, ':colour' => 'red'));
$red = $sth->fetchAll();
$sth->execute(array(':calories' => 175, ':colour' => 'yellow'));
$yellow = $sth->fetchAll();
?>
Кроме того, я бы рекомендовал использовать bindValue , чтобы сделать более явным то, что вы устанавливаете некоторые значения для заполнителей, таких какэто:
<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->bindValue(':calories', $calories, PDO::PARAM_INT);
$sth->bindValue(':colour', $colour, PDO::PARAM_STR);
$sth->execute();
?>