Try:
$sql = "INSERT INTO persist (user_id, hash, expire)
VALUES (:user_id, :hash, :expire)
ON DUPLICATE KEY UPDATE hash=:hash2";
and
$stm->execute(
array(":user_id" => $user_id,
":hash" => $hash,
":expire" => $future,
":hash2" => $hash)
);
Excerpt from the documentation (http://php.net/manual/en/pdo.prepare.php):
You must include a unique parameter marker for each value you wish to pass in to the statement when you call PDOStatement::execute(). You cannot use a named parameter marker of the same name twice in a prepared statement. You cannot bind multiple values to a single named parameter in, for example, the IN() clause of an SQL statement.