JDW
JDW

Reputation: 185

PHP sessions and class members

Ok, messing about with classes in PHP and can't get it to work the way I'm used to as a C++/Java-guy. In the "_init" function, if I run a query at the "// query works here" line", everythong works, but in the "getUserID" function, all that happens is said warning...

"getUserID" gets called from login.php (they are in the same dir):

login.php

<?php
include_once 'sitehandler.php';
include_once 'dbhandler.php';
session_start();

#TODO: Safer input handling
$t_userName = $_POST["name"];
$t_userId = $_SESSION['handler']['db']->getUserID($t_userName);

if ($t_userId != -1) {
    $_SESSION['user']['name'] = $t_userName;
    $_SESSION['user']['id'] = $t_userId;
}

//error_log("user: " . $_SESSION['user']['name'] . ", id: ". $_SESSION['user']['id']);
header("Location: " . $_SERVER["HTTP_REFERER"]);
?>

dbhandler.php

 <?php
include_once 'handler.php'; 

class DBHandler extends HandlerAbstract {
private $m_handle;

function __construct() {
    parent::__construct();
}

public function test() {
    #TODO: isdir liquibase
    #TODO: isfile liquibase-195/liquibase + .bat + execrights
    $this->m_isTested = true;
}

public function _init() {
    if (!$this->isTested()) $this->test();
    if (!file_exists('files/data.db')) {
        #TODO: How to to if host is Windows based?
        exec('./files/liquibase-1.9.5/liquibase --driver=org.sqlite.JDBC --changeLogFile=files/data_db.xml --url=jdbc:sqlite:files/data.db update');
        #TODO: quit if not success
    }

    #TODO: Set with default data
    try {
        $this->m_handle = new SQLite3('files/data.db');
    } catch (Exception $e) {
        die("<hr />" . $e->getMessage() . "<hr />");
    }

    // query works here
    $this->m_isSetup = true;
}

public function teardown() {

}

public function getUserID($name) {
    //  PHP Warning:  SQLite3::prepare(): The SQLite3 object has not been correctly initialised in
    $t_statement = $this->m_handle->prepare("SELECT id FROM users WHERE name = :name");
    $t_statement->bindValue(":name", $name, SQLITE3_TEXT);
    $t_result = $t_statement->execute();
        //var_dump($this->m_handle);

        return ($t_result)? (int)$t_result['id']: -1;
    }
}

Upvotes: 0

Views: 1006

Answers (1)

Andre
Andre

Reputation: 3181

When you place something in the session and the script ends, PHP goes through each object and calls the __sleep() magic function. Once it resumes the session, __wakeup() is called.

Resources are not stored in sessions. So every time you want to have a resource available to you, you must initialize it on every script run. This can easily be done, in your example, by implementing the __wakeup() magic method, which should call $this->_init();.

Your code could then become:

<?php

include_once 'handler.php';

class DBHandler extends HandlerAbstract { private $m_handle;

    function __construct() {
        parent::__construct();
    }

    public function test() {
        #TODO: isdir liquibase
        #TODO: isfile liquibase-195/liquibase + .bat + execrights
        $this->m_isTested = true;
    }

    public function _init() {
        if (!$this->isTested()) $this->test();
        if (!file_exists('files/data.db')) {
            #TODO: How to to if host is Windows based?
            exec('./files/liquibase-1.9.5/liquibase --driver=org.sqlite.JDBC --changeLogFile=files/data_db.xml --url=jdbc:sqlite:files/data.db update');
            #TODO: quit if not success
        }

        #TODO: Set with default data
        try {
            $this->m_handle = new SQLite3('files/data.db');
        } catch (Exception $e) {
            die("<hr />" . $e->getMessage() . "<hr />");
        }

        // query works here
        $this->m_isSetup = true;
    }

    public function teardown() {

    }

    public function getUserID($name) {
        //  PHP Warning:  SQLite3::prepare(): The SQLite3 object has not been correctly initialised in
        $t_statement = $this->m_handle->prepare("SELECT id FROM users WHERE name = :name");
        $t_statement->bindValue(":name", $name, SQLITE3_TEXT);
        $t_result = $t_statement->execute();
        //var_dump($this->m_handle);

        return ($t_result)? (int)$t_result['id']: -1;
    }

    /**
    * Start up the SQLite resource once
    * the session is started.
    * 
    */
    public function __wakeup() {
        $this->init();
    }
}

Upvotes: 1

Related Questions