6
votes

I have a terrible problem with pdo statements. My class generate a SQL Query based on the Object, then forward the query and params to Bd Class and execute, but data is inserted twice to database.

Table in database

CREATE TABLE IF NOT EXISTS `es_simple_object` (
    `id_object` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `active` tinyint(1) NOT NULL,

    PRIMARY KEY (`id_object`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Generated query

INSERT INTO es_simple_object (es_simple_object.id_object, es_simple_object.active) VALUES (NULL, ?)

Generated params array

Array
(
    [0] => 1
)

call Db function

static::$db = Db::getInstance();    
static::$db->_execute($sql, $params);

Bd Class (just functions used to this job)

    public static function getInstance()
    {
        if (!isset(self::$instance))
            self::$instance = new Db();

        return self::$instance;
    }

    private function __construct()
    {
        $connection = 'mysql:host='.$this->server.'; port='.$this->port.'; dbname='._DB_NAME_.'; charset='._DB_CHARSET_;

        try 
        {
            $this->link = new PDO($connection, _DB_USER_, _DB_PASSWD_);
            $this->link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } 
        catch (PDOException $ex) 
        {   
            Tools::_catchException($ex);

            exit;
        }

        return $this->link;
    }

    public function _execute($sql, $params = array())
    {
        try
        {           
            $pdoStatement = $this->link->prepare($sql);
            $pdoStatement->execute($params == null ? array(null) : $params);

            $this->rows_affected = $pdoStatement->rowCount();
            $this->rows_returned = $pdoStatement->columnCount();
            $this->last_id = $this->link->lastInsertId();
            $this->result = $pdoStatement;

            return $pdoStatement;
        }
        catch (PDOException $ex) 
        {
            Tools::_catchException($ex, array($sql, $params));

            return false;
        }
    }

I have no more ideas how to solve this problem

3
Could you also show your Db::getInstance() method? - marian0
@marian0 Yes, I updated the question - esik
Is it possible that your are calling the _execute function twice like in a loop or something. You can use debug_backtrace in your _execute function to see everytime it is called and from where. - Dan
@dan08 I checked this, but everything looks fine, function is called one time. I tried run this functions on localhost, the same result. - esik
I wrote a query by hand and call _execute function from index.php, but result is still the same - esik

3 Answers

3
votes

Why are you attempting to insert a NULL to the id_object column, when NULL is not allowed per the column constraints?

Instead, shouldn't you perhaps leave id_object out of the INSERT statement, and let MySQL add a new autoincremented value there?

1
votes

Thanks to @James Taylor for the suggestion of .htaccess file. The problem was hiding in RewriteRule and parameter QSA.

0
votes

Try adding some logging on the page that calls _execute() and include a timestamp. See if for some reason the page is being requested more than once.

If that is the case you should be able to track down whether it is due to something in .htaccess etc.

If that does nothing for you, try commenting out

$this->result = $pdoStatement;

        return $pdoStatement;

This way you can test to see if it has something to do with your calling $pdoStatement again.