CodeIgniter is inserting twice the same entry. In some cases

我是研究僧i 提交于 2020-01-01 19:21:39

问题


I am trying to figure out why Codeigniter is inserting 2 times the same row in my Database. I'm using PDO as interface for mySQL. I was debugging it and I am sure the function bellow is not being executed two times. It happens in a particular case, if the two foreache's don't run because the array is empty, but if one of them runs the error doesn't happen.

`

public function save_all() //save all information with the launched flag FALSE
{
    include(database_vars_url());
    try
    {
        $this->add_new_skills();

        if(!isset($_SESSION))
        {
            session_start();
        }
        $email = $_SESSION["email"];
        $sql = "INSERT INTO $tbl_name_contest (user_id, contest_title, contest_overview, contest_description,
                contest_category, contest_holder, contest_prize, contest_stage, contest_duration, contest_proj_duration,
                contest_level, contest_finalist, contest_winner, contest_create, contest_launched, contest_edit,
                contest_edit_id, contest_status, contest_delete)
                VALUES (0, '$this->title', '$this->overview', '$this->description', '$this->category',
                (SELECT customer_id FROM $tbl_name_customer WHERE user_id = 
                (SELECT user_id FROM $tbl_name_user WHERE user_email='$email')), '$this->prize', 0, '$this->contest_period',
                '$this->project_period', -1, -1, -1, NULL, DEFAULT, NULL, -1, -1, DEFAULT); ";

        foreach ($this->addon as $value)
        {
            $sql = $sql . "INSERT INTO $tbl_rel_contest_addon (add_contest_id, add_addon_id) 
                            VALUES ((SELECT contest_id FROM $tbl_name_contest WHERE contest_title = '$this->title'
                            AND contest_overview = '$this->overview' AND contest_prize = '$this->prize'),
                            (SELECT addon_id FROM $tbl_name_addon WHERE addon_name = '$value')); ";
        }

        foreach ($this->skills as $value)
        {
            $sql = $sql . "INSERT INTO $tbl_rel_contest_skill (required_contest_id, required_skill_id) 
                            VALUES ((SELECT contest_id FROM $tbl_name_contest WHERE contest_title = '$this->title'
                            AND contest_overview = '$this->overview' AND contest_prize = '$this->prize'),
                            (SELECT skill_id FROM $tbl_name_skill WHERE skill_name = '$value')); ";
        }
        echo $sql;
        return $this->db->query($sql);
    }
    catch(Exception $e)
    {
        echo $e->getMessage();
    }
    return 0;
}

Here I have a log of the mySQL, the first two SELECTS are called by "$this->add_new_skills();" at the beginning of the function save_all(). These SELECTs were supposed to be just one as well. This order SELECT SELECT, INSERT INSERT, proves that the function save_all() is not being called two times, if it were being called two times the order would be SELECT INSERT SELECT INSERT.

138 Connect root@localhost on repsero
138 Query SELECT skill_name FROM skill WHERE skill_status=2
138 Query SELECT skill_name FROM skill WHERE skill_status=2
138 Quit
139 Connect root@localhost on repsero
139 Quit
140 Connect root@localhost on repsero
140 Query INSERT INTO contest (user_id, contest_title, contest_overview, contest_description, contest_category, contest_holder, contest_prize, contest_stage, contest_duration, contest_proj_duration, contest_level, contest_finalist, contest_winner, contest_create, contest_launched, contest_edit, contest_edit_id, contest_status, contest_delete) VALUES (0, 'Contest Name', 'Overview of the contest Overview of the contest Overview of the contest Overview of the contest Overview of the contest Overview of the contest ', 'Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description ', 'SEO', (SELECT customer_id FROM customer WHERE user_id = (SELECT user_id FROM user WHERE user_email='customer@repsero.com')), '300', 0, '5','1', -1, -1, -1, NULL, DEFAULT, NULL, -1, -1, DEFAULT) 
140 Query INSERT INTO contest (user_id, contest_title, contest_overview, contest_description, contest_category, contest_holder, contest_prize, contest_stage, contest_duration, contest_proj_duration, contest_level, contest_finalist, contest_winner, contest_create, contest_launched, contest_edit, contest_edit_id, contest_status, contest_delete) VALUES (0, 'Contest Name', 'Overview of the contest Overview of the contest Overview of the contest Overview of the contest Overview of the contest Overview of the contest ', 'Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description Description ', 'SEO',(SELECT customer_id FROM customer WHERE user_id = (SELECT user_id FROM user WHERE user_email='customer@repsero.com')), '300', 0, '5', '1', -1, -1, -1, NULL, DEFAULT, NULL, -1, -1, DEFAULT)
140 Quit

回答1:


Well, I found out that the _execute() function in CI_DB_pdo_driver inside the codeigniter system was not working properly, maybe it is because of the php version. Anyway I changed the code of the CodeIgniter from:

    function _execute($sql)
{
    $sql = $this->_prep_query($sql);
    $result_id = $this->conn_id->prepare($sql);
    $result_id->execute();

    if (is_object($result_id))
    {
        if (is_numeric(stripos($sql, 'SELECT')))
        {
            $this->affect_rows = count($result_id->fetchAll());
            $result_id->execute();
        }
        else
        {
            $this->affect_rows = $result_id->rowCount();
        }
    }
    else
    {
        $this->affect_rows = 0;
    }

    return $result_id;
}

TO:

    function _execute($sql)
{
    $sql = $this->_prep_query($sql);
    $result_id = $this->conn_id->prepare($sql);
    $result_id->execute();

    if (is_object($result_id))
    {
        if (preg_match('/^\s*"?(SELECT)\s+/i', $sql))
        {
            $this->affect_rows = count($result_id->fetchAll());
            $result_id->execute();
        }
        else
        {
            $this->affect_rows = $result_id->rowCount();
        }
    }
    else
    {
        $this->affect_rows = 0;
    }

    return $result_id;
}

The part that tests if the $sql contains a "SELECT" inside it was not working, so when I tried to INSERT the "$result_id->execute()" was being called two times.



来源:https://stackoverflow.com/questions/19707273/codeigniter-is-inserting-twice-the-same-entry-in-some-cases

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!