Codeigniterを使用しています。すでに組み込まれているデータベースにセッションを保存する機能があります。
動作しないコードを削除して、代わりにCodeigniterの機能を使用してください。設定するだけです。
それとは別に、本当に「自分のものにとどまりたい」場合は、複数があります。 コードに問題があります。次の点に従えば、簡単に見つけることができます。
- セッション保存ハンドラーの各コールバック関数についてお読みください。特に、どのデータをどの形式で受信するか(そうしないと、「機能しない」と説明する動作をトリガーできるエラーが少なくとも1つ発生します)。
- エラーログを実行します。保存ハンドラーに問題があり、エラーが発生すると、ブラウザーへの出力ができなくなるため、エラーが表示されなくなる可能性があります。これには、エラーをファイルに記録する必要があります。これは、セッションsavehandlerを使用してトラブルシューティングを行う場合に非常に重要です。
- データベースインタラクションコードを邪魔にならないように移動します。これにより、データベースの相互作用が失敗した場合に、より適切なエラー情報を提供することもできます(そうしないと、「機能しない」と説明する動作を引き起こす可能性のあるエラーが少なくとも1つ隠されます)。
- 不要なコードを削除します。つまり、それは必要ありません。不要なコードがあると、ここにある「機能しない」シナリオにつながるエラーが含まれる可能性があります。ですから、あなたは理由もなく物事を成し遂げることを妨げています。一例:
ini_set("session.save_handler", "user");
-何をしているのかわからない限り、やらないでください。user
と呼ばれる事前定義されたsavehandlerはありません PHPでも、それを定義していません。
そしてそれは基本的にそれです。したがって、これを引き起こしている2つの実際のエラーを見つけることができます。将来の問題に対処できるように、他の手順が必要です。
- 常に同じデータベーステーブルに関連していることを確認してください。たとえば、テーブル
MY_SESSIONS
に書き込む場合 テーブルSESSIONS
から読み取ります 、これは機能しません。 - PHPに返すデータが、期待するデータと互換性があることを確認してください。たとえば、Base64でエンコードされたデータをデータベースに保存し、それをPHP Base64でエンコードして返す場合、PHPはそのデータで何もできません。
コードからは見えないその他の潜在的な問題:
- 使用しているデータベーススキーマは、そこに格納しているデータに適合していません(テーブルスキーマを指定していないため、問題が発生するかどうかはわかりません)。
- codeigniter自体がデータベース接続を作成しているため、データベースリンク識別子が変更される可能性があります。これは潜在的な副作用につながる可能性があります。データベース接続のリンク識別子を明示的に指定すると、リラックスした睡眠に役立ちます。
- データベース部分のエラー処理が欠落しているために気付かなかったSQLクエリのエラー。
コード例:
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
クラス:
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.');
}
}
}
エラー処理を伴うデータベース相互作用コード:
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);
}
}