DibDibs
DibDibs

Reputation: 566

PHP - PDO Query executing twice when execute() is only called once

I have looked everywhere for an answer to this and tried everything I have found here on StackOverflow and other sites.

Basically what's happening is that whenever I execute an SQL query, PDO is executing it twice even when execute() is only called once...

Here is my code...

<?php
namespace quizazle;

class sql{
  private $username = 'x';
  private $passwd = '';
  private $port = 3306;
  private $host = 'x';
  private $name = 'x';
  private $charSet = 'utf8mb4';

  private $db = null;

  public function __construct(){
    $this->db = new \PDO("mysql:host=$this->host;dbname=$this-    >name;charset=$this->charSet", $this->username, $this->passwd);
    $this->db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
    $this->db->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true);
    $this->db->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
  }

  private function bind($q, $p){
    try{
      $s = $this->db->prepare($q);
      if(!empty($p)){
        foreach ($p as $pm){
          $s->bindParam($pm['key'], $pm['value']);
        }
      }
    }
    catch(PDOException $e){
      echo($e->getMessage());
    }
    return $s;
  }

  public function query($query, $params){
    try{
      $statement = $this->bind($query, $params);
      $statement->execute();
      $res = $statement->fetchAll(\PDO::FETCH_BOTH);

      return $res;
    }
    catch(PDOException $e){
      echo($e->getMessage());
    }
  } 

  public function update($query, $params){
    try{
      $statement = $this->bind($query, $params);
      $statement->execute();
      $res = $statement->rowCount();

      return $res;
    }
    catch(PDOException $e){
      echo($e->getMessage());
    }
  }
}
?>

and here is the code where I am using the sql class...

$sql = new quizazle\sql();

$params = array(
  array(
    'key' => 'd',
    'value' => 'a'
  )
);

$result = $sql->update("INSERT INTO `test` (`data`) VALUES(:d)", $params);

var_dump($result);

I have tried...

yet none of this has worked. Any help will be greatly appreciated and thank you all in advance :)

PS: I discovered this problem while running INSERT statements, if that helps at all.

Upvotes: 1

Views: 1587

Answers (2)

DibDibs
DibDibs

Reputation: 566

I'm sorry for wasting all of your time, this was my stupid mistake.

You see, I was using Blisk which is a browser designed for developers. Since it is designed for developers, it has a function built-in that allows you to view your website as if it were on a mobile device, like this... enter image description here

When the page is loaded in this browser, it is loaded twice, once for the PC view and once for the mobile view. This means any PHP functions will be called twice, since the page is effectively being loaded twice, and that was the root of my problem.

There was nothing wrong with the code or the server, it was just me using Blisk that was the problem. Now that I'm back on Chrome, it's all alright!

I have flagged the problem to the Blisk devs, so hopefully something can be done to fix this! :)

Upvotes: 0

Your Common Sense
Your Common Sense

Reputation: 157892

  1. You wrote a very strange class that made your experience with database much worse than with vanilla PDO.
  2. Most likely your implementation of SEO-friendly URLS is no better.

To solve the first problem, leave PDO alone. Keep only one method in your class - query(), make it return PDOStatement:

public function query($query, $params) {
  $statement = $this->db->prepare($query);
  $statement->execute($params);
  return $statement;
} 

and utilize the method chaining to get different kinds of results from it. You may read detailed explanations in my article Your first database wrapper's childhood diseases. So your application code will become much cleaner:

$sql = new quizazle\sql();
$params = array('d' => 'a');
$result = $sql->query("INSERT INTO `test` (`data`) VALUES(:d)", $params);
var_dump($result->rowCount());

While for the second, just do not make your router script act as 404 handler. Run any controllers only if they are intended to, based on the request parameters. Do not run any SQL for the every request you get, but do it only for the requests you expect.

Upvotes: 1

Related Questions