You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Yii2中获取在线用户列表?需区分在线与已退出用户

Hey there! Let's break down how to get a list of online users in Yii2, plus how to tell apart active users from those who've logged out. I've got two reliable approaches for you:

This method is robust and works well for most applications. Here's how to set it up:

Step 1: Update Your User Table

First, add two fields to your user table (adjust names if needed):

  • last_active_at: Datetime field to store the user's last activity timestamp
  • is_online: Tinyint(1) field (0 for offline, 1 for online)

Step 2: Update Status on Login

When a user logs in successfully, update their online status and last active time:

// In SiteController's actionLogin method
if ($model->login()) {
    Yii::$app->user->identity->updateAttributes([
        'last_active_at' => date('Y-m-d H:i:s'),
        'is_online' => 1
    ]);
    return $this->goBack();
}

Step 3: Auto-Update Activity with a Behavior

To keep track of user activity as they navigate your site, create a global behavior that updates last_active_at periodically:

// Create app/components/UserActivityBehavior.php
namespace app\components;

use yii\base\Behavior;
use yii\web\Controller;
use Yii;

class UserActivityBehavior extends Behavior
{
    public function events()
    {
        return [
            Controller::EVENT_BEFORE_ACTION => 'updateLastActive',
        ];
    }

    public function updateLastActive()
    {
        if (!Yii::$app->user->isGuest) {
            $user = Yii::$app->user->identity;
            // Only update every 5 minutes to avoid excessive DB calls
            if (strtotime($user->last_active_at) < time() - 300) {
                $user->updateAttributes([
                    'last_active_at' => date('Y-m-d H:i:s'),
                    'is_online' => 1
                ]);
            }
        }
    }
}

Register this behavior in your config/web.php so it runs on every controller action:

'components' => [
    // ... other component configs
    'controller' => [
        'as userActivity' => [
            'class' => 'app\components\UserActivityBehavior',
        ],
    ],
],

Step 4: Mark User as Offline on Logout

When a user explicitly logs out, set their is_online status to 0:

// In SiteController's actionLogout method
public function actionLogout()
{
    if (!Yii::$app->user->isGuest) {
        Yii::$app->user->identity->updateAttributes(['is_online' => 0]);
    }
    Yii::$app->user->logout();
    return $this->goHome();
}

Step 5: Fetch Online/Offline Users

Add static methods to your User model to retrieve the lists:

// In models/User.php
public static function getOnlineUsers()
{
    // Consider users online if they've been active in the last 10 minutes
    $timeout = time() - 600;
    return self::find()
        ->where(['>', 'last_active_at', date('Y-m-d H:i:s', $timeout)])
        ->andWhere(['is_online' => 1])
        ->all();
}

public static function getLoggedOutUsers()
{
    // Users marked as offline OR inactive for over 10 minutes
    $timeout = time() - 600;
    return self::find()
        ->where(['is_online' => 0])
        ->orWhere(['<', 'last_active_at', date('Y-m-d H:i:s', $timeout)])
        ->all();
}
Approach 2: Track via Session/Cache (For Small Apps)

If you don't want to modify your database, you can use Yii2's cache component to track online users. Note: This is better for smaller apps since iterating over cache keys can be inefficient at scale.

Step 1: Store Session on Login

When a user logs in, store their session ID in cache with an expiration:

// After successful login
$userId = Yii::$app->user->id;
$sessionId = Yii::$app->session->id;
// Cache for 1 hour (adjust as needed)
Yii::$app->cache->set("online_user_{$userId}", $sessionId, 3600);

Step 2: Remove Cache on Logout

Delete the cache entry when the user logs out:

// In actionLogout
$userId = Yii::$app->user->id;
Yii::$app->cache->delete("online_user_{$userId}");

Step 3: Fetch Online Users

Retrieve all users with active cache entries:

// In User model
public static function getOnlineUsersViaCache()
{
    $keys = Yii::$app->cache->getKeys();
    $onlineUserIds = [];
    foreach ($keys as $key) {
        if (strpos($key, 'online_user_') === 0) {
            $userId = str_replace('online_user_', '', $key);
            $onlineUserIds[] = (int)$userId;
        }
    }
    return self::findAll(['id' => $onlineUserIds]);
}

Important Note

For users who close their browser without logging out, the database approach's timeout check will automatically mark them as offline after the set inactivity period. For the cache method, the cache entry will expire after the set time, removing them from the online list.

内容的提问来源于stack exchange,提问作者Angelo De Giacomo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 07:52:43