In Yii 2.0, Redis’s Active Record (Active Record), based on the ROW view structure, is inconsistent with the order of the model field.
1. In Yii 2.0, the active record of Redis (Active Record) is based on the view structure, which is inconsistent with the order of the model fields. as shown in Figure 1
2. Check the Redis activity record class, /common/models/redis/douyinwebappUserAccessToken.php
Yii::t('model/redis/douyin-web-app-user-access-token', 'ID'),
'douyin_web_app_id' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Douyin Web App Id'),
'channel_app_source_id' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Channel App Source Id'),
'channel_app_source_uuid' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Channel App Source Uuid'),
'douyin_web_app_user_id' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Douyin Web App User Id'),
'douyin_web_app_user_uuid' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Douyin Web App User Uuid'),
'grant_type' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Grant Type'),
'access_token' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Access Token'),
'expires_in' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Expires In'),
'expires_at' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Expires At'),
'refresh_token' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Refresh Token'),
'refresh_token_expires_in' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Refresh Token Expires In'),
'refresh_token_expires_at' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Refresh Token Expires At'),
'scope' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Scope'),
'open_id' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Open Id'),
'status' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Status'),
'is_deleted' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Is Deleted'),
'created_at' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Created At'),
'updated_at' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Updated At'),
'deleted_at' => Yii::t('model/redis/douyin-web-app-user-access-token', 'Deleted At'),
];
}
/**
* {@inheritdoc}
* @return DouyinWebAppUserAccessTokenQuery the active query used by this AR class.
*/
public static function find()
{
return new DouyinWebAppUserAccessTokenQuery(get_called_class());
}
}
3. Print the model object of redis (before the update), $redisdouyinWebAppUserAccessToken.
/**
* 基于 Access Token 插入/更新数据至抖音的第三方服务平台网站应用的用户的访问令牌(Redis)
* @param array $data 数据
* 格式如下:
*
* [
* 'douyinWebAppId' => 1, // 抖音的第三方服务平台网站应用ID
* 'channelAppSourceId' => 42, // 渠道的应用的来源ID
* 'channelAppSourceUuid' => '4dd4924a223d11ebb87054ee75d2ebc1', // 渠道的应用的来源ID(UUID)
* 'douyinWebAppUserId' => 4, // 抖音的第三方服务平台网站应用的用户ID
* 'douyinWebAppUserUuid' => '4dd5a770223d11eb988c54ee75d2ebc1', // 抖音的第三方服务平台网站应用的用户ID(UUID)
* 'grantType' => 'authorization_code', // 授权类型,authorization_code:第三方平台授权模式
* 'access_token' => 'act.fbb67f15948da5ab6d832b69daa58b7e3HEgNAeS3vv7hOBVqjNpjiJ1fZYY', // 访问令牌
* 'captcha' => '', //
* 'desc_url' => '', //
* 'description' => '', // 错误码描述
* 'error_code' => 0, // 错误码
* 'expires_in' => 1296000, // 访问令牌有效期,单位(秒)
* 'open_id' => '3c61649c-2cd5-4479-b2a3-0c89e8f808f8', // 授权第三方用户的用户唯一标识
* 'refresh_expires_in' => 2592000, // 刷新令牌有效期,单位(秒)
* 'refresh_token' => 'rft.1b82e0d7acbea76d68f45b44461e649fQzF6hSBGPuq9w7FVWv0cJ53J4aSg', // 刷新令牌
* 'scope' => 'fans.data,fans.list,following.list,im,user_info,video.comment,video.create,video.data,video.delete,video.list', // 权限范围
* ]
*
* @return array
* 格式如下:
*
* [
* 'status' => true, // 成功
* 'data' => [ // array
* 'channel_app_source_uuid' => 'ddb8822607ec11e9beda54ee75d2ebc1', // 渠道的应用的来源ID(UUID)
* ]
* ]
*
* [
* 'status' => false, // 失败
* 'code' => 214010, // 返回码
* 'message' => '', // 说明
* ]
*
* @throws ServerErrorHttpException
*/
public function saveModel($data)
{
/* 基于抖音的第三方服务平台网站应用的用户ID查找状态为启用的单个资源 */
$redisDouyinWebAppUserAccessToken = RedisDouyinWebAppUserAccessToken::find()->where(['douyin_web_app_user_id' => $data['douyinWebAppUserId']])->isDeletedNo()->enabled()->one();
if (!isset($redisDouyinWebAppUserAccessToken)) {
$redisDouyinWebAppUserAccessToken = new RedisDouyinWebAppUserAccessToken();
}
$time = time();
// 设置访问令牌的有效截止时间
$accessTokenExpireAt = $time + $data['expires_in'] - Yii::$app->params['accessToken']['timeOut'];
// 设置刷新令牌的有效截止时间
$refreshTokenExpireAt = $time + $data['refresh_expires_in'] - Yii::$app->params['refreshToken']['timeOut'];
$redisDouyinWebAppUserAccessToken->attributes = [
'douyin_web_app_id' => $data['douyinWebAppId'],
'channel_app_source_id' => $data['channelAppSourceId'],
'channel_app_source_uuid' => $data['channelAppSourceUuid'],
'douyin_web_app_user_id' => $data['douyinWebAppUserId'],
'douyin_web_app_user_uuid' => $data['douyinWebAppUserUuid'],
'grant_type' => $data['grantType'],
'access_token' => $data['access_token'],
'expires_in' => $data['expires_in'],
'expires_at' => $accessTokenExpireAt,
'refresh_token' => $data['refresh_token'],
'refresh_token_expires_in' => $data['refresh_expires_in'],
'refresh_token_expires_at' => $refreshTokenExpireAt,
'scope' => $data['scope'],
'open_id' => $data['open_id'],
'status' => RedisDouyinWebAppUserAccessToken::STATUS_ENABLED,
];
print_r($redisDouyinWebAppUserAccessToken);
exit;
$return = [];
if ($redisDouyinWebAppUserAccessToken->save()) {
$return = ['status' => true, 'data' => ['channel_app_source_uuid' => $data['channelAppSourceUuid']]];
} elseif ($redisDouyinWebAppUserAccessToken->hasErrors()) {
$firstError = '';
foreach ($redisDouyinWebAppUserAccessToken->getFirstErrors() as $message) {
$firstError = $message;
break;
}
$return = ['status' => false, 'code' => 215004, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '215004'), ['first_error' => $firstError]))];
} elseif (!$redisDouyinWebAppUserAccessToken->hasErrors()) {
throw new ServerErrorHttpException('Failed to insert/update the object (Douyin\'s third-party service platform website application user\'s access tokenn (Redis)) for unknown reason.');
}
return $return;
}
4. Print the model object of redis (before the update), $redisdouyinWebAppUserAccessToken. The result is as follows:
frontend\models\redis\DouyinWebAppUserAccessToken Object
(
[_attributes:yii\db\BaseActiveRecord:private] => Array
(
[douyin_web_app_id] => 1
[channel_app_source_id] => 46
[channel_app_source_uuid] => 24a4a41a225a11eb8b4a54ee75d2ebc1
[douyin_web_app_user_id] => 7
[douyin_web_app_user_uuid] => 24a5cc46225a11ebb31154ee75d2ebc1
[grant_type] => authorization_code
[access_token] => act.fbb67f15948da5ab6d832b69daa58b7e3HEgNAeS3vv7hOBVqjNpjiJ1fZYY
[expires_in] => 1296000
[expires_at] => 1606201312
[refresh_token] => rft.1b82e0d7acbea76d68f45b44461e649fQzF6hSBGPuq9w7FVWv0cJ53J4aSg
[refresh_token_expires_in] => 2592000
[refresh_token_expires_at] => 1607490412
[scope] => fans.data,fans.list,following.list,im,user_info,video.comment,video.create,video.data,video.delete,video.list
[open_id] => 3c61649c-2cd5-4479-b2a3-0c89e8f808f8
[status] => 1
)
)
5. Print the model object of redis (after the update), $redisdouyinwebAppUserAccessToken.
/**
* 基于 Access Token 插入/更新数据至抖音的第三方服务平台网站应用的用户的访问令牌(Redis)
* @param array $data 数据
* 格式如下:
*
* [
* 'douyinWebAppId' => 1, // 抖音的第三方服务平台网站应用ID
* 'channelAppSourceId' => 42, // 渠道的应用的来源ID
* 'channelAppSourceUuid' => '4dd4924a223d11ebb87054ee75d2ebc1', // 渠道的应用的来源ID(UUID)
* 'douyinWebAppUserId' => 4, // 抖音的第三方服务平台网站应用的用户ID
* 'douyinWebAppUserUuid' => '4dd5a770223d11eb988c54ee75d2ebc1', // 抖音的第三方服务平台网站应用的用户ID(UUID)
* 'grantType' => 'authorization_code', // 授权类型,authorization_code:第三方平台授权模式
* 'access_token' => 'act.fbb67f15948da5ab6d832b69daa58b7e3HEgNAeS3vv7hOBVqjNpjiJ1fZYY', // 访问令牌
* 'captcha' => '', //
* 'desc_url' => '', //
* 'description' => '', // 错误码描述
* 'error_code' => 0, // 错误码
* 'expires_in' => 1296000, // 访问令牌有效期,单位(秒)
* 'open_id' => '3c61649c-2cd5-4479-b2a3-0c89e8f808f8', // 授权第三方用户的用户唯一标识
* 'refresh_expires_in' => 2592000, // 刷新令牌有效期,单位(秒)
* 'refresh_token' => 'rft.1b82e0d7acbea76d68f45b44461e649fQzF6hSBGPuq9w7FVWv0cJ53J4aSg', // 刷新令牌
* 'scope' => 'fans.data,fans.list,following.list,im,user_info,video.comment,video.create,video.data,video.delete,video.list', // 权限范围
* ]
*
* @return array
* 格式如下:
*
* [
* 'status' => true, // 成功
* 'data' => [ // array
* 'channel_app_source_uuid' => 'ddb8822607ec11e9beda54ee75d2ebc1', // 渠道的应用的来源ID(UUID)
* ]
* ]
*
* [
* 'status' => false, // 失败
* 'code' => 214010, // 返回码
* 'message' => '', // 说明
* ]
*
* @throws ServerErrorHttpException
*/
public function saveModel($data)
{
/* 基于抖音的第三方服务平台网站应用的用户ID查找状态为启用的单个资源 */
$redisDouyinWebAppUserAccessToken = RedisDouyinWebAppUserAccessToken::find()->where(['douyin_web_app_user_id' => $data['douyinWebAppUserId']])->isDeletedNo()->enabled()->one();
if (!isset($redisDouyinWebAppUserAccessToken)) {
$redisDouyinWebAppUserAccessToken = new RedisDouyinWebAppUserAccessToken();
}
$time = time();
// 设置访问令牌的有效截止时间
$accessTokenExpireAt = $time + $data['expires_in'] - Yii::$app->params['accessToken']['timeOut'];
// 设置刷新令牌的有效截止时间
$refreshTokenExpireAt = $time + $data['refresh_expires_in'] - Yii::$app->params['refreshToken']['timeOut'];
$redisDouyinWebAppUserAccessToken->attributes = [
'douyin_web_app_id' => $data['douyinWebAppId'],
'channel_app_source_id' => $data['channelAppSourceId'],
'channel_app_source_uuid' => $data['channelAppSourceUuid'],
'douyin_web_app_user_id' => $data['douyinWebAppUserId'],
'douyin_web_app_user_uuid' => $data['douyinWebAppUserUuid'],
'grant_type' => $data['grantType'],
'access_token' => $data['access_token'],
'expires_in' => $data['expires_in'],
'expires_at' => $accessTokenExpireAt,
'refresh_token' => $data['refresh_token'],
'refresh_token_expires_in' => $data['refresh_expires_in'],
'refresh_token_expires_at' => $refreshTokenExpireAt,
'scope' => $data['scope'],
'open_id' => $data['open_id'],
'status' => RedisDouyinWebAppUserAccessToken::STATUS_ENABLED,
];
$return = [];
if ($redisDouyinWebAppUserAccessToken->save()) {
$return = ['status' => true, 'data' => ['channel_app_source_uuid' => $data['channelAppSourceUuid']]];
} elseif ($redisDouyinWebAppUserAccessToken->hasErrors()) {
$firstError = '';
foreach ($redisDouyinWebAppUserAccessToken->getFirstErrors() as $message) {
$firstError = $message;
break;
}
$return = ['status' => false, 'code' => 215004, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '215004'), ['first_error' => $firstError]))];
} elseif (!$redisDouyinWebAppUserAccessToken->hasErrors()) {
throw new ServerErrorHttpException('Failed to insert/update the object (Douyin\'s third-party service platform website application user\'s access tokenn (Redis)) for unknown reason.');
}
print_r($redisDouyinWebAppUserAccessToken);
exit;
return $return;
}
6. Print the model object of redis (after the update), $redisdouyinwebappUserAccessToken. in line with expectations. The order of the fields is the same as the definition. The result is as follows:
frontend\models\redis\DouyinWebAppUserAccessToken Object
(
[_attributes:yii\db\BaseActiveRecord:private] => Array
(
[douyin_web_app_id] => 1
[channel_app_source_id] => 48
[channel_app_source_uuid] => 73d70b7e225d11eb932654ee75d2ebc1
[douyin_web_app_user_id] => 8
[douyin_web_app_user_uuid] => 73d82e5a225d11eb932554ee75d2ebc1
[grant_type] => authorization_code
[access_token] => act.fbb67f15948da5ab6d832b69daa58b7e3HEgNAeS3vv7hOBVqjNpjiJ1fZYY
[expires_in] => 1296000
[expires_at] => 1606202733
[refresh_token] => rft.1b82e0d7acbea76d68f45b44461e649fQzF6hSBGPuq9w7FVWv0cJ53J4aSg
[refresh_token_expires_in] => 2592000
[refresh_token_expires_at] => 1607491833
[scope] => fans.data,fans.list,following.list,im,user_info,video.comment,video.create,video.data,video.delete,video.list
[open_id] => 3c61649c-2cd5-4479-b2a3-0c89e8f808f8
[status] => 1
[is_deleted] => 0
[deleted_at] => 0
[created_at] => 1604907033
[updated_at] => 1604907033
[id] => 2
)
)
7. Check the log of GUI for Redis to confirm the actual execution of the command. as shown in Figure 2
hscan cpa:ar:douyin_web_app_user_access_token:a:2 0 count 100
8. Open the console and execute the same command as above. Its response is consistent with the GUI. as shown in Figure 3
本地环境:10>hscan cpa:ar:douyin_web_app_user_access_token:a:2 0 count 100
1) "0"
2) 1) "id"
2) "2"
3) "channel_app_source_uuid"
4) "73d70b7e225d11eb932654ee75d2ebc1"
5) "refresh_token"
6) "rft.1b82e0d7acbea76d68f45b44461e649fQzF6hSBGPuq9w7FVWv0cJ53J4aSg"
7) "open_id"
8) "3c61649c-2cd5-4479-b2a3-0c89e8f808f8"
9) "created_at"
10) "1604907033"
11) "is_deleted"
12) "0"
13) "status"
14) "1"
15) "refresh_token_expires_at"
16) "1607491833"
17) "channel_app_source_id"
18) "48"
19) "expires_in"
20) "1296000"
21) "refresh_token_expires_in"
22) "2592000"
23) "deleted_at"
24) "0"
25) "douyin_web_app_id"
26) "1"
27) "access_token"
28) "act.fbb67f15948da5ab6d832b69daa58b7e3HEgNAeS3vv7hOBVqjNpjiJ1fZYY"
29) "grant_type"
30) "authorization_code"
31) "douyin_web_app_user_uuid"
32) "73d82e5a225d11eb932554ee75d2ebc1"
33) "expires_at"
34) "1606202733"
35) "updated_at"
36) "1604907033"
37) "douyin_web_app_user_id"
38) "8"
39) "scope"
40) "fans.data,fans.list,following.list,im,user_info,video.comment,video.create,video.data,video.delete,video.list"
本地环境:10>
9. In Yii 2.0, the active record of Redis (Active Record) is based on the Row view structure, which is in the same order as the model field (in another model with a similar structure). as shown in Figure 4
10. # Configure the maximum number of field fields, hash-max-zipmap-entries 512. # Configure the maximum byte limit of field values, hash-max-zipmap-value 64. When the above two conditions are met, the hash table key will be compressed, otherwise it will be stored according to the normal hash structure. Due to field: Scope values: fans.data,fans.list,following.list,im,user_info,video.comment,video.create,video.data,video.delete,video.list The maximum byte limit has been exceeded. Decide to modify the field: the value of scope is an empty string. View structure based on row, in the same order as the model field. Ultimately as expected. as shown in Figure 5




