public function PdoSessionHandler::write

File

drupal/core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php, line 161

Class

PdoSessionHandler
PdoSessionHandler.

Namespace

Symfony\Component\HttpFoundation\Session\Storage\Handler

Code

public function write($id, $data) {

  // get table/column
  $dbTable = $this->dbOptions['db_table'];
  $dbDataCol = $this->dbOptions['db_data_col'];
  $dbIdCol = $this->dbOptions['db_id_col'];
  $dbTimeCol = $this->dbOptions['db_time_col'];

  //session data can contain non binary safe characters so we need to encode it
  $encoded = base64_encode($data);
  try {
    $driver = $this->pdo
      ->getAttribute(\PDO::ATTR_DRIVER_NAME);
    if ('mysql' === $driver) {

      // MySQL would report $stmt->rowCount() = 0 on UPDATE when the data is left unchanged
      // it could result in calling createNewSession() whereas the session already exists in
      // the DB which would fail as the id is unique
      $stmt = $this->pdo
        ->prepare("INSERT INTO {$dbTable} ({$dbIdCol}, {$dbDataCol}, {$dbTimeCol}) VALUES (:id, :data, :time) " . "ON DUPLICATE KEY UPDATE {$dbDataCol} = VALUES({$dbDataCol}), {$dbTimeCol} = VALUES({$dbTimeCol})");
      $stmt
        ->bindParam(':id', $id, \PDO::PARAM_STR);
      $stmt
        ->bindParam(':data', $encoded, \PDO::PARAM_STR);
      $stmt
        ->bindValue(':time', time(), \PDO::PARAM_INT);
      $stmt
        ->execute();
    }
    elseif ('oci' === $driver) {
      $stmt = $this->pdo
        ->prepare("MERGE INTO {$dbTable} USING DUAL ON({$dbIdCol} = :id) " . "WHEN NOT MATCHED THEN INSERT ({$dbIdCol}, {$dbDataCol}, {$dbTimeCol}) VALUES (:id, :data, sysdate) " . "WHEN MATCHED THEN UPDATE SET {$dbDataCol} = :data WHERE {$dbIdCol} = :id");
      $stmt
        ->bindParam(':id', $id, \PDO::PARAM_STR);
      $stmt
        ->bindParam(':data', $encoded, \PDO::PARAM_STR);
      $stmt
        ->execute();
    }
    else {
      $stmt = $this->pdo
        ->prepare("UPDATE {$dbTable} SET {$dbDataCol} = :data, {$dbTimeCol} = :time WHERE {$dbIdCol} = :id");
      $stmt
        ->bindParam(':id', $id, \PDO::PARAM_STR);
      $stmt
        ->bindParam(':data', $encoded, \PDO::PARAM_STR);
      $stmt
        ->bindValue(':time', time(), \PDO::PARAM_INT);
      $stmt
        ->execute();
      if (!$stmt
        ->rowCount()) {

        // No session exists in the database to update. This happens when we have called
        // session_regenerate_id()
        $this
          ->createNewSession($id, $data);
      }
    }
  } catch (\PDOException $e) {
    throw new \RuntimeException(sprintf('PDOException was thrown when trying to write the session data: %s', $e
      ->getMessage()), 0, $e);
  }
  return true;
}