1

I am trying to implement a custom SessionHandler in PHP, that handles to session through a database using transactions.

The problem though, is that I keep getting a fatal errors, about the function being on null.

"Fatal error: Call to a member function begin_transaction() on null"
"Fatal error: Call to a member function commit() on null"

If I comment out the previous two I get:
"Fatal error: Call to a member function prepare() on null"
"Fatal error: Call to a member function close() on null"

Etc. Etc.

Now obviously, you would think that I forgot to initiate a connection with the database. Well, surprise, I have not.

<?php
    if (!empty($_POST)) {
        $username = trim($_POST['username']);
        $password = trim($_POST['password']);

        require_once '../psl-config.php';
        $db = new mysqli('localhost', USER, PASSWORD, DATABASE, 0, '/var/run/mysqld/mysqld.sock');

        if (!$db->connect_errno) {
            $login = $db->prepare('SELECT hashedPassword FROM gebruikerGegevens WHERE username = ?');
            $login->bind_param('s', $username);
            $login->execute();
            $login->bind_result($hashedPassword);
            $login->fetch();
        }

        if (password_verify($password, $hashedPassword)) {
            require_once 'sessionHandler.php';

            $handler = new MysqlSessionHandler($db);
            session_set_save_handler($handler);
            session_start();
        } else {
            echo "Username or password is incorrect.";
        }
    }
?>

Everything goes well until I initiate the MysqlSessionHandler function. NOTE: I have not inserted the rollback functions, as I still was busy figuring the bug out.

<?php
class MysqlSessionHandler implements SessionHandlerInterface {
    protected $db;

    public function open($save_path, $session_name) {
        return true;
    }

    public function read($session_id) {
        $db->begin_transaction(MYSQLI_TRANS_START_READ_WRITE);
        $db->prepare('SELECT expiry, data FROM sessions WHERE sid = ?');
        $db->bind_param('s', $session_id);
        $db->execute();
        $db->bind_result($expiry, $data);
        $result = $mysqli->fetch();

        if ($result) {
            if ($expiry < time()) {
                return '';
            }
            return $data;
        }

        //Inserts sessionID into database, if no sessionID could be found in the database.
        $db->prepare('INSERT INTO sessions (sid, expiry, data) VALUES (?,?,?)');
        $db->bind_param('sib', $session_id, $create_expiry, $empty_data);
        $create_expiry = session_cache_expire();
        $empty_data = '';
        $db->execute;
        return '';
    }

    public function write($session_id, $session_data) {
        $db->begin_transaction(MYSQLI_TRANS_START_READ_WRITE);
        $db->prepare('INSERT INTO sessions (sid, expiry, data) VALUES (?,?,?)');
        $db->bind_param('sib', $session_id, $create_expiry, $session_data);
        $create_expiry = session_cache_expire();
        $db->execute();
        return true;
    }

    public function close() {
        $db->commit();
        $db->close();
        return true;
    }

    public function  destroy($session_id) {
        $db->prepare('DELETE FROM sessions WHERE sid = ?');
        $db->bind_param('s', $session_id);
        $db->execute();
        return true;
    }

    public function gc($maxlifetime) {
        return true;
    }
}
?>
4
  • There is no variable named $db in the scope of your methods. Commented Dec 25, 2015 at 19:45
  • Start reading the documentation php.net/manual/en/language.oop5.basic.php Commented Dec 25, 2015 at 19:46
  • @PeeHaa The $db variable is passed when initiating the MysqlSessionHandler class itself? Just after when the password are checked. Commented Dec 25, 2015 at 21:50
  • @Berkan, please mark the answer as accepted if it solves your problem. Commented Dec 28, 2015 at 21:46

1 Answer 1

2

The $db variable is an instance variable, which means it must be referenced using $this.

Example

$this->db->begin_transaction(...);

But before being able to reference $db in this way, you have to set it using the constructor method.

class MysqlSessionHandler implements SessionHandlerInterface {
    protected $db;

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

    public function read(...) {
        ...
        $this->db->begin_transaction(...);
        $this->db->prepare(...);
        ...
    }
}
Sign up to request clarification or add additional context in comments.

Comments

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.