如何使用会话获取用户的在线时长?

时间:2012-04-26 07:49:11

标签: yii php

在yii中,我需要存储用户_login timelogout timetotal duration logged_使用会话。

我是会话概念的新手。我不知道如何检索total logged timelogin timelog out time。在会话表中,它仅存储id--expire--data

我存储会话的代码是

protected/config/main.php

            'components'=>array(

    'session'=>array(
            'class' => 'CDbHttpSession',

            'connectionID' => 'db',
            'sessionTableName' => 'dbsession',
        ),
    ),

所有工作正常,但存储在db中的数据是加密的。所以我无法检索到我需要的数据。还有一件事是什么数据存储在会话表中。

我使用的替代方式没有会话,但也有问题。我用它来获取login timelogout timetotal duration logged

我使用了带有字段的表活动

id,username,user_activity,url,ip,time 

当用户登录和注销低于

时填写表中数据的代码
protected/controller/sitecontrollers.php

         public function actionLogin()
        {
                /* log in */

                $model=new LoginForm;

                // if it is ajax validation request
                if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
                {
                        echo CActiveForm::validate($model);
                        Yii::app()->end();
                }

                // collect user input data
                if(isset($_POST['LoginForm']))
                {
                        $model->attributes=$_POST['LoginForm'];
                        // validate user input and redirect to the previous page if valid
                        if($model->validate() && $model->login())                                                                               
                               {
                                $activity = new Activity;
                                $activity->username = Yii::app()->user->id;                          
                                //$activity->userId = Yii::app()->user->id;
                                $activity->user_activity = "1";
                $activity->url=$_SERVER['HTTP_REFERER'];
                $activity->ip=$_SERVER['REMOTE_ADDR'];
                                // This breaks the site when log in details are wrong
                                $activity->save();
                                if($activity->save())
                                $this->redirect(Yii::app()->homeUrl);
                    }                          


                }

                // display the login form
      if(Yii::app()->user->id==null)
      {
                  $this->render('login',array('model'=>$model));
      }
         else
           {
         throw new CHttpException(404,'User already logged in.');
             }
        }

        /**
         * Logs out the current user and redirect to homepage.
         */
       public function actionLogout()
        {


                // log
                $activity = new Activity;
                $activity->username = Yii::app()->user->id;
                $activity->user_activity = "0";
        $activity->url=$_SERVER['HTTP_REFERER'];
        $activity->ip=$_SERVER['REMOTE_ADDR'];
                $activity->save();      


                Yii::app()->user->logout();   
                                if($activity->save())                                  

                $this->redirect(Yii::app()->homeUrl);
        }

通过这种方式所有工作都很好,但是当浏览器关闭时,应用程序将被注销,并且数据不会进入数据库。然后计算持续时间就会出错。所以只有我参加了方法会议,但不知道如何使用。

1 个答案:

答案 0 :(得分:4)

我认为你永远不会做出这样的事情而是犯了一些错误(或多或少几分钟,取决于你的需要)。

1。通过页面请求保持活力

您可以将活动状态发送到您的ajax页面actionImAlive,更常见的是,准确您将告诉用户会话的时间长度。如果你在5分钟内完成活着的东西 1次,那么你将有5分钟的错误。

  1. 添加列t_login,t_last_activity
  2. on用户登录更新t_login和t_last_activity及当前时间戳
  3. 在每个用户新页面加载检查是否需要更新t_last_activity

    主控制器*(components / Controller.php)

    public function keepAlive( ) {
            User::model()->updateByPk( 
                Yii::app()->user->id, 
               // array('t_last_activity' => 'NOW()') //CURRENT_TIMESTAMP
             array('t_last_activity' => new CDbExpression('NOW()')) //CURRENT_TIMESTAMP..this working fine 
        );
    }
    
    // Runs after any action in controller
    public function afterAction($action) {
        self::keepAlive();
        parent::afterAction($action);
    }
    
    // This action can be reached by ajax every 5min 
    // if user stays in one page long enaugh
    // (write javascript..)
    public function actionImAlive() {
        self::keepAlive();
    }
    
  4. 上面的代码每次用户加载新页面时都会更新t_last_activity,但您可以通过在用户会话中保存最后一个活动时间图并在执行keepAlive()函数之前检查它来每5分钟执行一次

    其他控制器

    所有其他控制器使用Controller类作为父级

    SiteController extends Controller
    MyController extends Controller
    SomeController extends Controller
    
  5. 2。仅限用户显示(计算从登录时间到现在的持续时间:now() - t_login

    如果你想向用户显示这个会话持续时间(你为什么要这样做我不知道,但无论如何..)你可以只将t_login列添加到用户表并计算持续时间一只苍蝇。

    这些是我的头脑。