Опитайте:
$sql = "INSERT INTO persist (user_id, hash, expire)
VALUES (:user_id, :hash, :expire)
ON DUPLICATE KEY UPDATE hash=:hash2";
и
$stm->execute(
array(":user_id" => $user_id,
":hash" => $hash,
":expire" => $future,
":hash2" => $hash)
);
Извадка от документацията (http://php.net/manual/en/pdo. подготви.php ):
Трябва да включите уникален маркер за параметър за всяка стойност, която искате да предадете на израза, когато извикате PDOStatement::execute(). Не можете да използвате два пъти наименуван маркер за параметър със същото име в подготвен оператор. Не можете да свързвате множество стойности към един наименуван параметър в, например, клаузата IN() на SQL израз.