简体   繁体   中英

php database singleton does not return second result

I'm new to all of this so please excuse me if I've done something daft. I realise I probably have. But I've been trying to get this to work for 2 days now and I'm really stuck.

I have a simple database singleton as below:

define('SERVER',$config["serverName"]);
define('USERNAME',$config["userName"]);
define('PASSWORD',$config["password"]);
define('DATABASE',$config["databaseName"]);

class DbClass{

    private static $instance;
    private $conn;

    private function __construct(){
        $this->conn = new mysqli(SERVER, USERNAME, PASSWORD, DATABASE);
    }

    public static function init(){
        if(is_null(self::$instance)){
            self::$instance = new DbClass();
        }
        return self::$instance;
    }

    public function callQuery($query){
        $result = null;
        try{
            $result = $this->conn->query($query);
        }
        catch(Exception $e){
            return $e->getMessage();
        }
        return $result;
    }
}

I have a simple test file where I am trying to call a stored procedure twice and access the result. It all works the first time, but the second time I call it, I get a null result. Here's the simple test file:

require_once '../utility/DbClass.php';

$conn = DBClass::init();
$query4a = "CALL selectMaxBaseline(218)";
$result = $conn->callQuery($query4a);
var_dump($conn);
var_dump($result);

$queryA = "CALL selectMaxBaseline(218)";
try{
    $result2 = $conn->callQuery($queryA);
}
catch(Exception $e) {
    echo $e->getMessage();
}
var_dump($conn);
var_dump($result2);

The $conn object looks good and I get the same object back both times I call var_dump. Which is what I would expect. I can iterate through the $result the first time round and see it's returning the right data. So I know the database connection is good, the stored procedure works and it returns a valid result (I've removed this code for brevity). But the $result object is false for the second call. No errors are returned. Here's the output from running the file:

object(DbClass)[1]
  private 'conn' => 
    object(mysqli)[2]
      public 'affected_rows' => null
      public 'client_info' => null
      public 'client_version' => null
      public 'connect_errno' => null
      public 'connect_error' => null
      public 'errno' => null
      public 'error' => null
      public 'error_list' => null
      public 'field_count' => null
      public 'host_info' => null
      public 'info' => null
      public 'insert_id' => null
      public 'server_info' => null
      public 'server_version' => null
      public 'stat' => null
      public 'sqlstate' => null
      public 'protocol_version' => null
      public 'thread_id' => null
      public 'warning_count' => null
object(mysqli_result)[3]
  public 'current_field' => null
  public 'field_count' => null
  public 'lengths' => null
  public 'num_rows' => null
  public 'type' => null
object(DbClass)[1]
  private 'conn' => 
    object(mysqli)[2]
      public 'affected_rows' => null
      public 'client_info' => null
      public 'client_version' => null
      public 'connect_errno' => null
      public 'connect_error' => null
      public 'errno' => null
      public 'error' => null
      public 'error_list' => null
      public 'field_count' => null
      public 'host_info' => null
      public 'info' => null
      public 'insert_id' => null
      public 'server_info' => null
      public 'server_version' => null
      public 'stat' => null
      public 'sqlstate' => null
      public 'protocol_version' => null
      public 'thread_id' => null
      public 'warning_count' => null
boolean false

I've tried various things without any success. Any ideas gratefully received.

It turns out that the first query has not been 'used' by the time the second query fires and mysqli does not allow concurrent queries. So the trick is to 'clear' the first query, then fire the second query.

I changed the function to:

public function callQuery($query){
    try{
        while($this->conn->more_results()) {
            $this->conn->next_result();
            $this->conn->use_result();
        }
        $result = $this->conn->query($query);
        return $result;
    }
    catch(Exception $e){
        return $e->getMessage();
    }
}

and now everything works as expected. Both calls to callQuery return the correct result as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM