Sombrero123
Sombrero123

Reputation: 33

Query Inside a redis model in yii2

I have created a redis model, which should store statistics like this:

<?php

namespace app\models;

use Yii;
use yii\base\Model;
use \yii\redis\ActiveRecord;
use \yii\redis\ActiveQuery;

class StatsModel extends ActiveRecord
{

    public function attributes()
    {
        return ['id', 'hits', 'user', 'ua', 'ip','os'];
    }
    public function rules()
    {
        return [
            ['user', 'required'],
            ['user','string'],
            ['ip', 'required'],
            ['ip', 'integer'],
            ['hits', 'integer'],
            ['ua','string'],
            ['os','integer']
        ];
    }
    public static function total_user_hits($username)
    {
        $query = new ActiveQuery($this);
        $query->find()->where('user = '.$user)->all();
    }
    public static function getDb()
    {

        return \Yii::$app->db_redis;
    }
}

Now, i'm trying to make a static function, which i can use, to count all thi hits value for specific user in redis. I'm creating an $query = new ActiveQuery($this); each time in the function, but can how can initiliase just one copy of the query to always use it? If i do it like class property:

public $query = new ActiveQuery($this);

I get error expression is not allowed as field default value

Upvotes: 0

Views: 290

Answers (1)

rob006
rob006

Reputation: 22174

You should not reuse existing query object (unless you want to make query with the same conditions) - ActiveQuery is mutable, it means that previous queries may change its state:

$query = new ActiveQuery(StatsModel::class);
$result1 = $query->andWhere('user = 1')->all(); // 1 result

$result2 = $query->andWhere('user = 2')->all(); // no results

Second query will not return anything, since it will create condition like WHERE user = 1 AND user = 2 which is always false.

If you're afraid about performance, you should not. Creating ActiveQuery object has negligible overhead. Creating objects in PHP is relatively cheap and ActiveQuery is quite lightweight - the most time consuming thing will be actual query to redis/db.

Upvotes: 1

Related Questions