Jeff Jeff - 2 months ago 7
MySQL Question

PHP PDO Dependancy Injection

thanks for reading and considering my question..

I am new to PDO and to OOP (the right way - I've been using objects more like functions for some time now), and I'm attempting to convert my current user login scripts to prevent session hijacking (whilst at the same time make getting data from the database easier)... anyway...

Additionally - I am doing this to learn, not because I need a login script. If I needed something like this I would use a framework that's already out there that has been proven.

I'm constructing this class for UserSessions, defined thusly:

class UserSession {
public $userSessionId;
public $loggedInUserId;
public $userIp;
public $userFwdIp;
public $httpUserAgent;
public $authenticated;

private $hashedPassword;
private $suppliedUserName;
private $suppliedPassword;

public function __construct ($pdoConn) {
$this->setUserSessionId();
$this->setUserIp();
$this->setUserFwdIp();
$this->setSessionExpire();
$this->setHttpUserAgent();
$this->setLoggedInUserId();
$this->updateCurrentSession();
}
private function setLoggedInUserId() {
$query = 'select 1 from dual';
$this->loggedInUserId = $pdoConn->query($query)->fetch()[0];
}
// several other methods below that all function properly
}


I instantiate the class here:

$databaseConnect = new $config['database_type']($config);
$pdoConn = new PDO( $databaseConnect->connectString
, $databaseConnect->getDataBaseUser()
, $databaseConnect->getDataBasePass()
, array(PDO::ATTR_EMULATE_PREPARES=>false
, pdo::ATTR_ERRMODE=>pdo::ERRMODE_EXCEPTION)
);
$httpReqUser = new UserSession($pdoConn);


However, I get the below error:
Call to a member function query() on null

So, this is telling me that the $pdoConn object is null (I think)... but I can't figure out why.

I have tried setting a new variable to the $pdoConn value that's passed in from outside of the constructor for local use like this:

$this->setPdoConn($pdoConn) // and within that method it's a simple setter...

Perhaps I'm misunderstanding what exactly I should* be doing here.

Basically - this UserSession class will need to update or insert a few fields into a table, nevertheless it will need access to PDO, but I don't want to have to call a 'new PDO' every time I want to use it in all of my classes... How should I approach this?

Answer

Your constructor receives a $pdoConn parameter, but you aren't doing anything with it.

Create a class attribute, save $pdoConn in the constructor, and then use that to issue queries.

Like this:

class UserSession {
    private $pdoConn;
    // rest of your class attributes

    public function __construct ($pdoConn) {
        $this->pdoConn = $pdoConn;
        // rest of your constructor
    }

    private function setLoggedInUserId() {
        $this->loggedInUserId = $this->pdoConn->query(...)->fetch()[0];
    }
}