public function PdoSessionHandler::write in Zircon Profile 8
Same name and namespace in other branches
- 8.0 vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php \Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler::write()
File
- vendor/
symfony/ http-foundation/ Session/ Storage/ Handler/ PdoSessionHandler.php, line 322
Class
- PdoSessionHandler
- Session handler using a PDO connection to read and write data.
Namespace
Symfony\Component\HttpFoundation\Session\Storage\HandlerCode
public function write($sessionId, $data) {
$maxlifetime = (int) ini_get('session.gc_maxlifetime');
try {
// We use a single MERGE SQL query when supported by the database.
$mergeSql = $this
->getMergeSql();
if (null !== $mergeSql) {
$mergeStmt = $this->pdo
->prepare($mergeSql);
$mergeStmt
->bindParam(':id', $sessionId, \PDO::PARAM_STR);
$mergeStmt
->bindParam(':data', $data, \PDO::PARAM_LOB);
$mergeStmt
->bindParam(':lifetime', $maxlifetime, \PDO::PARAM_INT);
$mergeStmt
->bindValue(':time', time(), \PDO::PARAM_INT);
$mergeStmt
->execute();
return true;
}
$updateStmt = $this->pdo
->prepare("UPDATE {$this->table} SET {$this->dataCol} = :data, {$this->lifetimeCol} = :lifetime, {$this->timeCol} = :time WHERE {$this->idCol} = :id");
$updateStmt
->bindParam(':id', $sessionId, \PDO::PARAM_STR);
$updateStmt
->bindParam(':data', $data, \PDO::PARAM_LOB);
$updateStmt
->bindParam(':lifetime', $maxlifetime, \PDO::PARAM_INT);
$updateStmt
->bindValue(':time', time(), \PDO::PARAM_INT);
$updateStmt
->execute();
// When MERGE is not supported, like in Postgres, we have to use this approach that can result in
// duplicate key errors when the same session is written simultaneously (given the LOCK_NONE behavior).
// We can just catch such an error and re-execute the update. This is similar to a serializable
// transaction with retry logic on serialization failures but without the overhead and without possible
// false positives due to longer gap locking.
if (!$updateStmt
->rowCount()) {
try {
$insertStmt = $this->pdo
->prepare("INSERT INTO {$this->table} ({$this->idCol}, {$this->dataCol}, {$this->lifetimeCol}, {$this->timeCol}) VALUES (:id, :data, :lifetime, :time)");
$insertStmt
->bindParam(':id', $sessionId, \PDO::PARAM_STR);
$insertStmt
->bindParam(':data', $data, \PDO::PARAM_LOB);
$insertStmt
->bindParam(':lifetime', $maxlifetime, \PDO::PARAM_INT);
$insertStmt
->bindValue(':time', time(), \PDO::PARAM_INT);
$insertStmt
->execute();
} catch (\PDOException $e) {
// Handle integrity violation SQLSTATE 23000 (or a subclass like 23505 in Postgres) for duplicate keys
if (0 === strpos($e
->getCode(), '23')) {
$updateStmt
->execute();
}
else {
throw $e;
}
}
}
} catch (\PDOException $e) {
$this
->rollback();
throw $e;
}
return true;
}