Sarah S. Sarah S. - 3 months ago 7
MySQL Question

MySQL's session handler difficulities

Watching this online tutorial about MYSQL's session handler and got really confused about this part, I hope someone could help me out:

table_XXX
== Table XXX;
col_XXX
== Column XXX;
sid
== Session id

Read method:

public function read($session_id)
{
$this->db->exec('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
$this->db->beginTransaction();
/**
* the data is selected and no other ppl can interfere
* the writing process until COMMIT is reached
*/
$sql = "SELECT $this->col_expiry, $this->col_data
FROM $this->table_sess
WHERE $this->col_sid = :sid FOR UPDATE";
$selectStmt = $this->db->prepare($sql);
$selectStmt->bindParam(':sid', $session_id);
$selectStmt->execute();
$results = $selectStmt->fetch(\PDO::FETCH_ASSOC);
if ($results) {
if ($results[$this->col_expiry] < time()) {
// return empty if data out of date
return '';
}
return $results[$this->col_data];
}

return $this->initializeRecord($selectStmt);
}


Protected method:

protected function initializeRecord(\PDOStatement $selectStmt)
{
try {
$sql = "INSERT INTO $this->table_sess
($this->col_sid, $this->col_expiry, $this->col_data)
VALUES (:sid, :expiry, :data)";
$insertStmt = $this->db->prepare($sql);
$insertStmt->bindParam(':sid', $session_id);
$insertStmt->bindParam(':expiry', $this->expiry); // expiry is defined
$insertStmt->bindValue(':data', '');
$insertStmt->execute();
return '';
} catch(\PDOException $e) {
$this->db->rollBack();
throw $e;
}
}


Write method:

public function write($session_id, $data)
{
try {
$sql = "INSERT INTO $this->table_sess ($this->col_sid,
$this->col_expiry, $this->col_data)
VALUES (:sid, :expiry, :data)
ON DUPLICATE KEY UPDATE
$this->col_expiry = :expiry,
$this->col_data = :data";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':expiry', $this->expiry, \PDO::PARAM_INT);
$stmt->bindParam(':data', $data);
$stmt->bindParam(':sid', $session_id);
$stmt->execute();
return true;
} catch (\PDOException $e) {
if ($this->db->inTransaction()) {
$this->db->rollback();
}
throw $e;
}
}


In 'Protected method', line 8, there is a $session_id, and clearly no $session_id is passed to the protected method, so bindParam() for that line simply binded nothing?
So initializeRecord() simply initiated a row that has expiry time but nothing else? And then the sid and data is inserted after write method is called?

Answer

This is doing a lot of string-construction trickery with WHERE $this->col_sid = :sid and so forth, as it creates SQL statements.

You might try echoing or dumping those SQL statements to see what they contain right before you run ->execute() on them. That will help you troubleshoot.

It's pretty clear your protected method is missing $session_id. Is it possible there's a value for $this->sid you could use there?