PDO错误:PDOStatement :: execute():SQLSTATE [HY093]:参数号无效:绑定变量数与令牌数不匹配

Got error when trying to generate and execute sql query dynamically. I double check the query executed and everything looks fine but I still get this error. What am I doing wrong here?

PHP Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

Here's the code:

$data = array();

$params = [
            'planid' => $_POST['planid'], 
            'email' => $_POST['email'], 
            'firstname' => $_POST['firstname'],
            'lastname' => $_POST['lastname']
        ];  


foreach ($params as $key => $value) {
        $data[':'.$key] = $value;
}


print_r($data);

//OUTPUT:

Array
(  
    [:planid] => GBP001
    [:email] => juandelacruz@myemail.com
    [:firstname] => Juan
    [:lastname] => De La Cruz
)


$sql = "INSERT INTO user (";
            $count = count($params);
            $x=1;

            foreach ($params as $k => $v) {
                $sql .= " $k ";
                if($x<$count)
                    $sql .= ",";
                $x++;
            }
                $sql .= " ) SELECT ";
            $y=1;
            foreach ($params as $k => $v) {
                $sql .= " :$k ";
                if($y<$count)
                    $sql .= ",";
                $y++;
            }
                $sql .= " FROM DUAL WHERE NOT EXISTS( SELECT * FROM user u
                            WHERE u.email = :email AND u.planid = :planId )";


var_dump($sql);

//OUTPUT:

 INSERT INTO user ( planid , email , firstname , lastname  ) SELECT  :planid , :email , :firstname , :lastname FROM DUAL WHERE NOT EXISTS( SELECT * FROM user u WHERE u.email= :email AND u.planid = :planId)






$pdo = Database::getInstance();
$stmt = $pdo->prepare($sql);
$stmt->execute($data);


print_r($stmt);
//OUTPUT:

PDOStatement Object
(
    [queryString] => INSERT INTO user ( planid , email , firstname , lastname ) SELECT :planid , :email , :firstname , :lastname  FROM DUAL WHERE NOT EXISTS(SELECT * FROM user u
                                    WHERE u.email= :email AND u.planid = :planid)
)