既然你能 记录每次会员登录的session id(显然要保存到数据库里)
那么你就直接将 session 的文件方式改成数据库方式不就得了
想踢哪个就把相应的记录删去就是了

解决方案 »

  1.   

    谢谢版主回答,可以不可以说得详细点,我现在是将session id保存在数据库里面,关键是客户端呀,比如你在后台获取了某个会员的session id,如何将客户端那边的session失效,这样就能踢出会员了,版主说的删除相应的记录是什么意思?用PHP不久,见笑了
      

  2.   

    session是存放在服务器的,你删除后客户端的session就获取不到了只能重新登录。
      

  3.   

    我想知道怎么做啊,怎么删除,查了一下函数只有session_destroy(),这个函数还没有参数,只能删除本帐号登录的SESSION,要删除其它的通过SESSIONID怎么删除呢
      

  4.   

    版主意思是把session保存在db而不是保存在文件,因为你session id已经保存在db了,可以把session都保存在db,这样方便操作。然后根据session id来删除对应的db记录来实现了。如果session是保存在文件的,也可以通过session id来删除文件实现。
    session文件的保存位置是 session.save_path,可用phpinfo(); 查到session_start();
    $_SESSION['test'] = 1;
    echo session_id();以上代码执行后,例如session_id()返回 iak6l6lurg6o63a00tsdi0a4m5
    在session.save_path中会生成 sess_iak6l6lurg6o63a00tsdi0a4m5 文件,这个就是session文件。
    然后根据iak6l6lurg6o63a00tsdi0a4m5 这个session id执行删除文件操作就可以了。
      

  5.   

    版主如果按照这样的方式那我删除了某一个用户的session id,用户每次访问一个页面的时候都还要查询一次数据库,判断session id还存在不,如果不存在就证明被T下线了,是这样吗?
      

  6.   

    用unlink ($myfile);删除文件的时候提示没有权限,怎么获取权限才能够删除session 的文件呢?
      

  7.   

    session_set_save_handler 到数据库方式后
    相关操作由 php 自动完成,无需你在写代码文件方式的 session 临时文件在用户操作期间是被锁定的,你只有在用户两次操作之间用
    session_id(用户的sessionid);
    session_unset();
    session_write_close();
    来删除该sessionid的临时文件
      

  8.   

    明白了,我犯了一个错误,应该删除其它session id的文件,而不是正在访问的session id,还有版主请教一下你,你说的
    session_set_save_handler到数据库方式后,相关操作由PHP自动完成,请问是什么意思,我的意思是说,如果我要踢掉一个用户,把数据库中这个用户的session id值设置为空,然后被踢掉的这个用户再访问其它页面的时候,再查询一次自己的session id,如果为空就被T掉了,我现在的理解是这样,不知道对不对,是这样吗,版主,希望指点一下,感激!!!
      

  9.   

    对是这样的,没有了 sessionid 对应的记录,就得重新登录了
      

  10.   

    版主不好意思再请教一下你,这样一个php文件怎么用呢
    <?php 
    /*============================文件说明======================================== 
    @filename: session.class.php 
    @description: 数据库保存在线用户session,实现在线用户功能! 
    @notice: session过期时间一个小时,因为我们的站点是使用cookie(有效时间是1小时)登录。 
    因此我们只记录用户登录的时间,而不是刷新一次更新一次 
    删除数据库中session记录的动作发生在用户超时后执行这个文件或正常退出(session_destory) 
    @database: database:sessions field:sessionid(char32),uid(int10),last_visit(int10) 
    =============================================================================
    */
    class session {
    private $db;
    private $lasttime=3600;//超时时间:一个小时
    function session(&$db) {
    $this->db = &$db;
    session_module_name('user'); //session文件保存方式,这个是必须的!除非在Php.ini文件中设置了
    session_set_save_handler(
    array(&$this, 'open'), //在运行session_start()时执行
    array(&$this, 'close'), //在脚本执行完成或调用session_write_close() 或 session_destroy()时被执行,即在所有session操作完后被执行
    array(&$this, 'read'), //在运行session_start()时执行,因为在session_start时,会去read当前session数据
    array(&$this, 'write'), //此方法在脚本结束和使用session_write_close()强制提交SESSION数据时执行
    array(&$this, 'destroy'), //在运行session_destroy()时执行
    array(&$this, 'gc') //执行概率由session.gc_probability 和 session.gc_divisor的值决定,时机是在open,read之后,session_start会相继执行open,read和gc
    );
    session_start(); //这也是必须的,打开session,必须在session_set_save_handler后面执行
    }
    function unserializes($data_value) {
    $vars = preg_split(
    '/([a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*)|/', 
    $data_value, -1, PREG_SPLIT_NO_EMPTY |
    PREG_SPLIT_DELIM_CAPTURE
    );
    for ($i = 0; isset($vars[$i]); $i++) {
    $result[$vars[$i++]] = unserialize($vars[$i]);
    }
    return $result;
    }
    function open($path, $name) {
    return true;
    }
    function close() {
    $this->gc($this->lasttime);
    return true;
    }
    function read($SessionKey){
    $sql = "SELECT uid FROM sessions WHERE session_id = '".$SessionKey."' limit 1";
    $query =$this->db->query($sql);
    if($row=$this->db->fetch_array($query)){
    return $row['uid'];
    }else{
    return "";
    }
    }
    function write($SessionKey,$VArray) {
    require_once(MRoot.DIR_WS_CLASSES .'db_mysql_class.php');
    $db1=new DbCom();
    // make a connection to the database... now
    $db1->connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD, DB_DATABASE);
    $db1->query("set names utf8");
    $this->db=$db1;
    $SessionArray = addslashes($VArray);
    $data=$this->unserializes($VArray);
    $sql0 = "SELECT uid FROM sessions WHERE session_id = '".$SessionKey."' limit 1";
    $query0 =$this->db->query($sql0);
    if($this->db->num_rows($query0)<=0){
    if (isset($data['webid']) && !empty($data['webid'])) {
    $this->db->query("insert into `sessions` set `session_id` = '$SessionKey',uid='".$data['webid']."',last_visit='".time()."'");
    }
    return true;
    }else{
    /*$sql = "update `sessions` set ";
     if(isset($data['webid'])){
     $sql .= "uid = '".$data['webid']."', " ;
     }
     $sql.="`last_visit` = null "
     . "where `session_id` = '$SessionKey'";
     $this->db->query($sql); */
    return true;
    }
    }
    function destroy($SessionKey) {
    $this->db->query("delete from `sessions` where `session_id` = '$SessionKey'");
    return true;
    }
    function gc($lifetime) {
    $this->db->query("delete from `sessions` where unix_timestamp(now()) -`last_visit` > '".$this->lasttime."'");
    return true;
    }
    }
    ?>
    其它页面要用到这个技术,是不是每个页面都要引入这个类并且创建一个session类的对象呢,每个session 失效的时候是不是会调用函数destroy跟gc函数呢
      

  11.   

    用unlink ($myfile);删除文件的时候提示没有权限,怎么获取权限才能够删除session 的文件呢?我测试过可以啊,你删的是自己正在使用的session文件吗?那当然不行
      

  12.   

    用unlink ($myfile);删除文件的时候提示没有权限,怎么获取权限才能够删除session 的文件呢?我测试过可以啊,你删的是自己正在使用的session文件吗?那当然不行
    确实,我删除正在使用的,怪不得不行,session_set_save_handler这种方法应该是最好的,我试试看
      

  13.   

    <?php$con = mysql_connect("127.0.0.1", "root" , "111111");mysql_select_db("session");function open($save_path, $session_name) {
        return(true);
    }function close() {
        return(true);
    }function read($id) {
        if ($result = mysql_query("select * from session where id='$id'")) {        if ($row = mysql_fetch_array($result)) {
                return $row["data"];
            }
        } else {
            return "";
        }
    }function write($id, $sess_data) {

        $sql = "SELECT * FROM session WHERE id = '".$id."' limit 1";
        $check=mysql_query($sql);
        $total=mysql_num_rows($check);
        $result = false;
        if($total<=0){
         $sql = "insert into `session` set `id` = '$id',data='".$sess_data."',last_visit='".time()."'";
         mysql_query($sql);
        }else{
         $sql = "update session set data='$sess_data', last_visit='".time()."' where id='$id'";
         $result = mysql_query($sql);
        }

        if ($result==true) {
            return true;
        } else {
            return false;
        }
    }function destroy($id) {    if ($result = mysql_query("delete * from session where id='$id'")) {
            return true;
        } else {
            return false;
        }
    }function gc($maxlifetime) {
        $sql = "delete from `session` where unix_timestamp(now()) -`last_visit` > '60'";
        $result = mysql_query($sql);
        if ($result == true) {
            echo $sql;
            return true;    } else {
            echo "error";
            return false;    }}session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
    @ini_set('session.gc_probability', 1);
    @ini_set('session.gc_divisor', 2);
    @ini_set('session.gc_maxlifetime', 60);
    session_start();?>//文件名session_user_start.php
    版主求指点一下,我写了2个页面测试,
    1.php
    <?php   include 'session_user_start.php';
      
      $_SESSION['test'] ="ok la";
      
      echo "init ok";
     
    ?>另外一个
    2.php
    <?php   include 'session_user_start.php';
      echo $_SESSION['test'];
    ?>
    可以访问,但是60秒以后再去访问2.php发现gc那个函数并没有调用,请教一下怎么样才能在session失效的时候,访问2.php让GC这个 函数执行呢
      

  14.   

    gc那个可以写一个crontab实现。
    http://blog.csdn.net/fdipzone/article/details/7263361
      

  15.   

    gc有调用了,但是发现,其它页面引入include 'session_user_start.php';
      echo $_SESSION['test'];,发现在以前页面赋值的SESSION到了引入的session的页面,$_SESSION的值为空了,奇怪
      

  16.   

    知道是什么原因了read的时候要返回session的数据,这样引入到其它页面的时候才会得到session数据
      

  17.   

    使用static数组和session同时保存用户名+登录时间,验证的时候取session的数据和数组的数据比较,可行吗