【问题标题】:Storing Sessions in a DB in PHP - keep getting mysql error在 PHP 中将会话存储在数据库中 - 不断收到 mysql 错误
【发布时间】:2010-06-02 22:37:31
【问题描述】:

我想将我所有的会话存储在一个数据库中,并阅读了这个并实现了以下类:

<?php
/**
* This class handles users sessions and stores the session in the DB rather than in a file. This way stops any 
* shared host security problems that could potentially happen. 
*/
class sessionHandler {

    /**
    * Initial constructor which takes the database object as a param, to do all the database stuff
    * @param object $db The datase object
    */
    public function __construct ($db) {
        $this->db = $db;
        $this->setHandler();    
    }

    function setHandler() {

        session_set_save_handler(array(&$this, "open"),
                                array(&$this, "close"),
                                array(&$this, "read"),
                                array(&$this, "write"),
                                array(&$this, "destroy"),
                                array(&$this, "clean")
                               );           
    }

    /**
    * Initiate a database object if necessary
    */
    function open() {
        $this->db->connect();
    }

    /**
    * Write session id and data to the database
    * @param string $id The hashed 32 char session id, unique to a user
    * @param string $data Serialized session array from the unique session
    * @return id The newly inserted ID of the database
    */
    function write($id, $data) { 
        $access = time();
        $dateAdded = date("Y-m-d G:i:s");

        $this->db->wrapper->where(array("sessionId"=>$id));
        $this->db->query($this->db->wrapper->delete(__CLASS__));

        //fopen a file and store this in it that way we can debug
        $query = $this->db->wrapper->insert(__CLASS__, array("sessionId"=>$id,"dateAdded"=>$dateAdded,"sessionData"=>$data));

        $this->db->query($query);
        return $this->db->insertId();
    }

    /**
    * Retrieve the session data for a given session id
    * @param string $id The hashed 32 char session id, unique to a user
    * @return string The session data found for the given session id
    */
    function read($id) {
        $id = $this->db->wrapper->escape($id);
        $row = $this->db->fetch(1, $this->db->wrapper->get_where(__CLASS__,array("sessionId"=>$id)), array(),false);
        if ($row) {
            return $row['data'];    
        }
        return "";
    }

    /**
    * Delete a session from the database by its unique session id
    * @param string $id The hashed 32 char session id, unique to a user
    * @return integer The number of deleted rows - should only ever be 1
    */
    function destroy($id) { 
        $id = $this->db->wrapper->escape($id);
        $this->db->wrapper->where(array("sessionId"=>$id));
        $this->db->query($this->db->wrapper->delete(__CLASS__));
        return $this->db->affectedRows();
    }

    /**
    * Garage collector which deletes old records in the database, delete sessions that have expired. This is
    * determined by the session.gc_maxlifetime variable in the php.ini 
    * @param integer $max The maximum number of seconds allowed before a session is to be considered expired
    * @return integer The number of deleted rows
    */
    function clean($max) {
        $old = time() - $max;
        $old = $this->db->wrapper->escape($old);
        $this->db->wrapper->where(array("access"=>$old), "<");
        $this->db->query($this->db->wrapper->delete(__CLASS__));
        return $this->db->affectedRows();

    }

    /**
    * Close the database connection once a read / write has been complete
    */
    function close() {
        $this->db->close(); 
    }

    /**
    * End the current session and store session data. 
    */
    public function __destruct(){
        session_write_close();
    }       
}

正如您在我的代码中看到的,我将 DB 对象作为参数传递给类。我的引导文件如下:

    $db = mogDB::init(); 
    $sh = new sessionHandler($db);

    session_start();

我在这里使用了一些我自己的类,所以 MogDB:init() 基本上创建了一个具有正确凭据的数据库连接。包装的东西基本上是这样我不必在 sql 查询之后输入 sql 查询(我猜我有点懒)。

但我得到的问题是我的 php 错误日志中的这个:

08-Apr-2010 17:40:31] PHP Warning:  mysql_insert_id(): 11 is not a valid MySQL-Link resource in /library/mysql.php on line 69 

我已经尽可能多地调试了它,似乎当它尝试将会话写入数据库时​​,它失败了。我已经设法将查询保存到一个文件中,并通过 phpmyadmin 很好地导入到数据库中,所以问题不是查询。

mysql.php第69行如下:

68. public function insertId() {
69.     return mysql_insert_id($this->id);
70. }

任何帮助将不胜感激 谢谢

【问题讨论】:

  • 天哪,您每次请求会话值以及每次更改会话值时都在运行 MySQL 查询???哇,哇。
  • 请在第 69 行附近包含文件 /library/mysql.php 的内容,以便我们查看那里发生的情况。这就是报告的错误。
  • @animuson 有没有更好的方法?使用session_set_save_handler() 似乎意味着它每次都在执行读/写操作。唯一的区别是内置的使用文件而不是数据库。

标签: php mysql database session resources


【解决方案1】:

在您在第 69 行包含文件 /library/mysql.php 的内容后,我们可以看到那里发生了什么,我猜您的一小部分代码要求返回数据库句柄以调用 mysql_insert_id ,相反,您的 db api 已经返回了实际的 insertID...

【讨论】:

  • 我现在在 mysql.php 中添加了第 68,69 和 70 行
  • 在上面的错误警告之前我也得到了这个错误:mysql_query(): 11 is not a valid MySQL-Link resource in /library/mysql.php on line 43
  • 对不起 Zak,我不明白你的意思,请你再解释一下
  • 嗨 Zak,我现在已经解决了这个问题,但感谢您的建议。我发现在写函数中,我需要再次连接到数据库
猜你喜欢
  • 2015-10-09
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 2013-03-01
  • 1970-01-01
相关资源
最近更新 更多