1

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...

  • removing var_dump($result);
  • not binding parameters, although that is a bad way to go for me, it still doesn't work.
  • changing $this->db->setAttribute(\PDO::ATTR_EMULATE_PREPARES, true); to $this->db->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
  • changing $this->db->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); to $this->db->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

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.

8
  • 1
    How do you see that the query gets performed twice and not that the server actually gets two requests? Commented Sep 16, 2016 at 21:52
  • 3
    Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example. Commented Sep 16, 2016 at 21:52
  • 1
    You discovered this with an INSERT query, yet you're posting the code that revolves around an UPDATE. There's nothing indicating that execute gets called twice. Also, the class you created - it's not really doing you any favors, is it? It's more complicated than using PDO without "object oriented" code. How come you are not using ORM libraries available to PHP? If you're dabbling with this, I understand intellectual curiosity, but if you're trying to do some actual work - why reinvent the wheel? There's nothing here that we can use to reproduce, so Charlotte is quite correct. Commented Sep 16, 2016 at 21:55
  • 1
    You should be using bindValue, not bindParam, in the bind() method, because bindParam binds to references. You're binding all the parameters to the last parameter. Commented Sep 16, 2016 at 22:27
  • 2
    Nothing you've shown would explain why the code is running twice. The most likely reason is that something is calling your script twice. Check your server log to see how many calls there are to the script. Commented Sep 16, 2016 at 22:32

2 Answers 2

1
  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.

Sign up to request clarification or add additional context in comments.

1 Comment

Sorry I haven't seen this yet, I've been away, and it's still adding 2 rows into my table.
0

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! :)

2 Comments

that's what I told you in my answer exactly. Nowhere it's a Blisk problem, but only your application's design flaw.
@YourCommonSense not really a reason to downvote though. Anyway, how would you even go about doing that, how do you 'expect' a request?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.