Hãy thử:
$sql = "INSERT INTO persist (user_id, hash, expire)
VALUES (:user_id, :hash, :expire)
ON DUPLICATE KEY UPDATE hash=:hash2";
và
$stm->execute(
array(":user_id" => $user_id,
":hash" => $hash,
":expire" => $future,
":hash2" => $hash)
);
Trích từ tài liệu ( http://php.net/manual/en/pdo. chuẩn bị.php ):
Bạn phải bao gồm một điểm đánh dấu tham số duy nhất cho mỗi giá trị bạn muốn chuyển vào câu lệnh khi bạn gọi PDOStatement ::execute (). Bạn không thể sử dụng một điểm đánh dấu tham số đã đặt tên của cùng một tên hai lần trong một câu lệnh đã chuẩn bị. Bạn không thể liên kết nhiều giá trị với một tham số được đặt tên, chẳng hạn như mệnh đề IN () của câu lệnh SQL.