0

I am getting irritated by this error. I keep getting mysqli::query(): Couldn't fetch database on a mysqli query.

Here is my mysqli extended class (database.php) :

class database extends mysqli {

    private $host;
    private $username;
    private $password;
    private $database;
    private $name;
    private $connected;
    public $status;

    public function __construct( $param ) {

        $this->host = $param['host'];
        $this->username = $param['username'];
        $this->password = $param['password'];
        $this->database = $param['name'];   

        @parent::__construct( $this->host, $this->username, $this->password, $this->database );

        $this->status = ($this->connect_errno) ? "Not Connected ( Because of Error )" : "Connected";
        $this->connected = ($this->connect_errno) ? false : true;
    }

    public function stop() {
        if( $this->connected ) { $this->close(); }
        $this->status = "Not Connected ( Manually Disconnected )";
    }

}

And here is where i use the query (sessions.php) :

class session {

    private $db;

    public function __construct( $db ) {
        $this->db = $db;
    }

    function open() {
        return true;
    }

    function close() {
        return true;
    }

    function read( $id ) {


        $sql = "SELECT * FROM sessions WHERE sessionid = '{$id}'";
        $sqlq = $this->db->query( $sql );
        if( $sqlq ) { $row = $sqlq->fetch_assoc(); return $row['data']; }
        else { return ''; }

    }

    function write( $id, $data ) {

        $now = time();

        $sql = "SELECT * FROM sessions WHERE sessionid = '{$id}'";

        $sqlq = $this->db->query( $sql ); // HERE I GET THE ERROR

        if( ( $sqlq ) && ( $sqlq->num_rows == 1 ) ) { $sql = "UPDATE sessions SET data = '{$data}', updated = {$now} WHERE sessionid = '{$id}'"; return $this->db->query( $sql ); }
        else { $sql = "INSERT INTO sessions ( sessionid, updated, data ) VALUES ( '{$id}', {$now}, '{$data}' )"; return $this->db->query( $sql ); }

    }

    function destroy( $id ) {

        return $this->db->delete( "FROM sessions WHERE sessionid = '{$id}'" );

    }

    function clean( $max ) {

        $old = time() - $max;

        return $this->db->delete( "FROM sessions WHERE updated < {$old}" );

    }

}

This is how i use them in the main file (main.php):

<?
    $params = array();
    $params['host'] = XXXXXXXXXXXXX;
    $params['username'] = XXXXXXXXXXXXX;
    $params['password'] = XXXXXXXXXXXXX;
    $params['name'] = XXXXXXXXXXXXX;

    include("database.php");
    include("sessions.php");

    $db = new database( $params );
    $session = new session( $db );
    session_set_save_handler( array($session, "open"), array($session, "close"), array($session, "read"), array($session, "write"), array($session, "destroy"), array($session, "clean") );
    session_start();

?>
  • You never instantiate the session class so there is no way (with the shared code) to get that error there – PeeHaa Aug 05 '15 at 09:23
  • @PeeHaa it was a mistake while typing the question, i do instantiate it right after `$db`, i edited the question. – Denis Makula Aug 05 '15 at 09:25
  • Why are you using the STFU (`@`) operator? – PeeHaa Aug 05 '15 at 09:46
  • @PeeHaa to ignore the error if there is one, but i catch it with the _errno a line under. – Denis Makula Aug 05 '15 at 10:11
  • So you are ignoring errors and now you are asking us what the error is? – PeeHaa Aug 05 '15 at 10:19
  • 2
    @PeeHaa I do not feel your comments to be too helpful or friendly, any PHP programmer would know that, that @ mark only ignores connection errors, i do not have any. – Denis Makula Aug 05 '15 at 10:29
  • So you don't want people to ask for clarification when information is broken or missing in your question? – PeeHaa Aug 05 '15 at 12:07
  • @PeeHaa The question you asked shouldn't clarify anything if you knew what you are doing, there was no broken or missing information about the @ mark and about the fact that I am ignoring connection errors. Besides that, it was asked in an extremely unfriendly and unprofessional way, I am not here to teach communication manners, so please ignore this post completely and thank you for trying to help. – Denis Makula Aug 05 '15 at 13:19

2 Answers2

0

Ok, I partially figured it out by myself. Anyway, it would be great if an experienced PHP developer would explain this more clearly for future issues and questions from other people.

It seems that if i check the status of my mysqli connection inside a session method, it shows up "Manually Disconnected", which means that $db->stop() have been called. I only call that function at the end of my index.php (the base index from my project) which basically means that everything that happens inside the session class happens AFTER the whole 'outside' PHP code have been run.

I have fixed my problem by opening another connection of my database class (The extension of mysqli), and using that connection inside session class.

-1

The read function should work ok, but the write function will not work with the same connection.

the best way is to create a connection inside your session object specific for the class itself.

It will be something like this:

class session {

  private $db;

  public function __construct( $params ) {
    $this->db = new database( $params );
  }
  .
  .
  .
}

and then create your session object like this:

$session = new session( $params );
EhsanT
  • 2,041
  • 3
  • 26
  • 29
  • That way you only tightly couple the database class to the session class without any war to swap it out. Also that would mean you cannot reuse the database connection elsewhere. – PeeHaa Aug 05 '15 at 11:43
  • Are you sure about this? thanks for the downvote anyway! how come I can not reuse the database connection elsewhere? there is not any better logical way to achieve this. either you have to create the new connection manually inside the class or use the db class – EhsanT Aug 05 '15 at 11:51
  • "Are you sure about this?" Yes, very sure. "thanks for the downvote anyway!" You're welcome. Note I vote based on content not based on feelings. "how come I can not reuse the database connection elsewhere?" Because you coupled the instance of the database connection to the session class. "either you have to create the new connection manually inside the class or use the db class" Yes which is exactly what OP is doing. Passing the instance (with the connection) to classes / methods that need it [What is dependency injection](http://stackoverflow.com/questions/130794/what-is-dependency-injection) – PeeHaa Aug 05 '15 at 12:00
  • @PeeHaa as far as I know, the `write function` is called when the `DB Instance` is destroyed. So you do not have access to the instance directly. that was the main cause of the OP's question. so you can not pass the db instance to this specific class. – EhsanT Aug 05 '15 at 12:21
  • That's why the actual problem (the destroying of the instance) should be fixed instead of duct-taping a solution – PeeHaa Aug 05 '15 at 12:24
  • again as far as I know you can not fix it in this specific case(handling sessions manually) – EhsanT Aug 05 '15 at 12:25
  • Perhaps I am missing something that you are seeing, but why would a session handler be any different from any random other class when it comes to passing in a database connection? – PeeHaa Aug 05 '15 at 12:31
  • Please take a look at [here](http://php.net/manual/en/function.session-set-save-handler.php) the methods of this class are callback functions calling automatically by `PHP`. so here is what is written about `write function`: _This callback is invoked when PHP shuts down_. that's the main reason that the `db instance` is destroyed before calling this function. – EhsanT Aug 05 '15 at 12:35
  • Actually this is what I have done before you answered. You don't actually need to use the same connection elsewhere as @PeeHaa mentioned in the first comment, you can only use a database connection inside the session class and another outside of it. It seems like a waste and there MAY or MAY NOT be a better solution. But this one works. I would upvote but I am not currently able to because of my reputation. I am new. – Denis Makula Aug 05 '15 at 13:26
  • @EhsanT If you take a look at the comments on the question post, you can see that Peehaa is pretty much only trying to make an impression without having an actual big volume of knowledge. For others he may be a little missleading in my opinion and he should be mostly ignored. – Denis Makula Aug 05 '15 at 13:31
  • @DenisMakula First, I'm glad that you could sort out the problem. Second, about PeeHaa's comments, based on his reputation, I do not think what you said is correct. his comments looked a little aggressive, but I'm sure he know what he's saying :) – EhsanT Aug 05 '15 at 13:39
  • @EhsanT He may be extremely good in any other department of PHP, anyway I hope this answer gets upvoted, else there may be others in the same situation being stuck. – Denis Makula Aug 05 '15 at 13:43