Você está usando o Codeigniter. Ele tem o recurso de armazenar sessões no banco de dados já embutido.
Basta remover seu código que não funciona e usar o recurso do Codeigniter. Você só precisa configurá-lo.
Além disso, se você realmente quer "ficar com os seus", existem vários problemas com seu código. Eles são fáceis de detectar se você seguir os seguintes pontos:
- Leia sobre cada função de retorno de chamada para o manipulador de salvamento de sessão. Especialmente quais dados eles recebem e em qual formato (não fazer isso leva a pelo menos um erro capaz de desencadear o comportamento que você descreve como "não está funcionando").
- Faça o registro de erros. Ter um problema com o manipulador de salvamento que leva a erros pode deixá-los invisíveis porque a saída para o navegador não é mais possível. Isso requer que você registre erros no arquivo. Isso é muito importante ao solucionar problemas com um manipulador de salvamento de sessão.
- Afaste o código de interação do banco de dados. Isso permite que você também forneça melhores informações de erro caso a interação com o banco de dados falhe (não fazer isso oculta pelo menos um erro que pode resultar no comportamento que você descreve como "não está funcionando").
- Remova o código desnecessário. Quer dizer, não é necessário. Ter código que não é necessário pode incluir erros que resultam no cenário "não está funcionando" que você tem aqui. Então você está se impedindo de fazer as coisas sem motivo. Um exemplo:
ini_set("session.save_handler", "user");
- enquanto você não tem idéia do que você faz, não faça. Não há um manipulador de salvamento predefinido chamadouser
em PHP, nem você está definindo isso.
E é basicamente isso. Para que eu pudesse identificar dois erros reais causando isso, as outras etapas são necessárias para que você possa lidar com problemas futuros:
- Certifique-se de estar sempre relacionado à mesma tabela de banco de dados. Por exemplo, se você escrever na tabela
MY_SESSIONS
e leia da tabelaSESSIONS
, isso nunca funcionará. - Certifique-se de que os dados que você devolve ao PHP são compatíveis com os dados esperados. Por exemplo, se você armazenar os dados codificados em Base64 no banco de dados e devolvê-los ao PHP codificado em Base64, não há nada que o PHP possa fazer com esses dados.
Outros problemas potenciais que não são visíveis no seu código:
- O esquema de banco de dados que você tem não é adequado para os dados que você armazena nele (você não forneceu o esquema da tabela, então não pode ser dito se isso causa ou não problemas).
- O identificador do link do banco de dados pode ser alterado porque o próprio codeigniter está criando uma conexão com o banco de dados. Isso pode levar a possíveis efeitos colaterais. Fornecer explicitamente o identificador de link para a conexão com o banco de dados ajuda a ter um sono tranquilo.
- Erros em consultas SQL que passaram despercebidos porque o tratamento de erros para as partes do banco de dados está ausente.
Código de exemplo:
ob_start();
session_name("test");
session_set_cookie_params(0, '/', '.test.com');
$s = new SessionManagement();
$s->register();
session_start();
ECHO $_SESSION['test'], "\n"; # value
SessionManagement
refatorado classe:class SessionManagement
{
private $_timeout;
private $_db;
public function __construct() {
$CI =& get_instance();
$CI->load->database();
$this->_db = new LegacyMysqlDatabase(
$CI->db->hostname, $CI->db->username, $CI->db->password, $CI->db->database
);
$this->_timeout = 60 * 60 * 10;
}
public function _open() {
return TRUE;
}
public function _close() {
return TRUE;
}
public function _read($session_id) {
$db = $this->_db;
$session_id = $db->escape($session_id);
$sql = "SELECT session_data
FROM SESSION
WHERE session_id = '$session_id'";
if (!($result = $db->query($sql)) || !$result->getNumberOfRows()) {
return '';
}
$record = $result->fetchAssoc();
return $record['session_data'];
}
public function _write($session_id, $session_data) {
$db = $this->_db;
$session_id = $db->escape($session_id);
$session_data = $db->escape($session_data);
$session_expires = time() + $this->_timeout;
$sql = "REPLACE INTO SESSION (session_id, session_data, session_expires)
VALUES ('$session_id', '$session_data', $session_expires)";
return (bool)$db->query($sql); // cast to bool because PHP would cast to int
}
public function _gc($max) {
return TRUE;
}
public function _destroy($id) {
$db = $this->_db;
$session_id = $db->escape($id);
$sql = "DELETE
FROM SESSION
WHERE session_id = '$id'";
return $db->query($sql);
}
public function register() {
$registered = session_set_save_handler(
array($this, '_open'),
array($this, '_close'),
array($this, '_read'),
array($this, '_write'),
array($this, '_destroy'),
array($this, '_gc')
);
if (!$registered) {
throw new Exception('Can not register session savehandler.');
}
}
}
Código de interação do banco de dados com tratamento de erros:
class LegacyMysqlDatabase
{
private $_hostname;
private $_username;
private $_password;
private $_database;
private $_link;
private $_initError = false;
public function __construct($hostname, $username, $password, $database) {
$this->_hostname = $hostname;
$this->_username = $username;
$this->_password = $password;
$this->_database = $database;
}
public function query($sql) {
$link = $this->getLink();
$result = mysql_query($sql, $link);
if ($result === false) {
trigger_error(sprintf('Query "%s" failed: #%d: %s', $sql, mysql_errno($link), mysql_error($link)));
throw new Exception('Failed to query Mysql database.');
}
return new LegacyMysqlResult($result);
}
public function escape($string) {
return mysql_real_escape_string($string, $this->getLink());
}
private function getLink() {
if ($this->_initError) {
throw new Exception('Failed to initialize the database.');
}
if ($this->_link === null) {
$this->_initError = true;
$result = mysql_connect($this->_hostname, $this->_username, $this->_password);
if (!$result) {
throw new Exception('Can not connect to Mysql database.');
}
$this->_link = $result;
$selected = mysql_select_db($this->_database, $this->_link);
if (!$selected) {
trigger_error(sprintf('Can not select Mysql database "%s": #%d: %s', $this->_database, mysql_errno($result), mysql_error($result)));
throw new Exception(sprintf('Can not select Mysql database "%"', $this->_database));
}
$this->_initError = false;
}
return $this->_link;
}
}
class LegacyMysqlResult
{
private $_result;
public function __construct($result) {
$this->_result = $result;
}
public function getNumberOfRows() {
return mysql_num_rows($this->_result);
}
public function fetchAssoc() {
return mysql_fetch_assoc($this->_result);
}
}