sql >> データベース >  >> RDS >> Mysql

PHPデータベースへのセッションの保存。読み取りメソッドが機能していないようです

    Codeigniterを使用しています。すでに組み込まれているデータベースにセッションを保存する機能があります。

    動作しないコードを削除して、代わりにCodeigniterの機能を使用してください。設定するだけです。

    それとは別に、本当に「自分のものにとどまりたい」場合は、複数があります。 コードに問題があります。次の点に従えば、簡単に見つけることができます。

    1. セッション保存ハンドラーの各コールバック関数についてお読みください。特に、どのデータをどの形式で受信するか(そうしないと、「機能しない」と説明する動作をトリガーできるエラーが少なくとも1つ発生します)。
    2. エラーログを実行します。保存ハンドラーに問題があり、エラーが発生すると、ブラウザーへの出力ができなくなるため、エラーが表示されなくなる可能性があります。これには、エラーをファイルに記録する必要があります。これは、セッションsavehandlerを使用してトラブルシューティングを行う場合に非常に重要です。
    3. データベースインタラクションコードを邪魔にならないように移動します。これにより、データベースの相互作用が失敗した場合に、より適切なエラー情報を提供することもできます(そうしないと、「機能しない」と説明する動作を引き起こす可能性のあるエラーが少なくとも1つ隠されます)。
    4. 不要なコードを削除します。つまり、それは必要ありません。不要なコードがあると、ここにある「機能しない」シナリオにつながるエラーが含まれる可能性があります。ですから、あなたは理由もなく物事を成し遂げることを妨げています。一例:ini_set("session.save_handler", "user"); -何をしているのかわからない限り、やらないでください。 userと呼ばれる事前定義されたsavehandlerはありません PHPでも、それを定義していません。

    そしてそれは基本的にそれです。したがって、これを引き起こしている2つの実際のエラーを見つけることができます。将来の問題に対処できるように、他の手順が必要です。

    1. 常に同じデータベーステーブルに関連していることを確認してください。たとえば、テーブルMY_SESSIONSに書き込む場合 テーブルSESSIONSから読み取ります 、これは機能しません。
    2. PHPに返すデータが、期待するデータと互換性があることを確認してください。たとえば、Base64でエンコードされたデータをデータベースに保存し、それをPHP Base64でエンコードして返す場合、PHPはそのデータで何もできません。

    コードからは見えないその他の潜在的な問題:

    1. 使用しているデータベーススキーマは、そこに格納しているデータに適合していません(テーブルスキーマを指定していないため、問題が発生するかどうかはわかりません)。
    2. codeigniter自体がデータベース接続を作成しているため、データベースリンク識別子が変更される可能性があります。これは潜在的な副作用につながる可能性があります。データベース接続のリンク識別子を明示的に指定すると、リラックスした睡眠に役立ちます。
    3. データベース部分のエラー処理が欠落しているために気付かなかった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);
        }
    }
    


    1. MySQLはアルファベット順にソートしますが、無視します

    2. UDFがサブクエリよりもはるかに遅いのはなぜですか?

    3. MySQLデータベースでフルネームまたはファーストネームまたはラストネームを別々の列のファーストネームとラストネームで検索する

    4. ホームステッド-データベースに接続しています