原型
~~~
<?php
namespace app\index\controller;
use app\index\model\LLogin;
use app\index\model\LRegister;
use app\index\model\Retention;
use think\Controller;
header("Content-type: text/html; charset=utf-8");
/**
* Cronret compute()方法由系统Command类命令行程序定期调用,实现用户留存信息计算
*/
class Cronret extends Controller
{
/*
* '1' 注册用户数,日活跃用户计算
* '2' 次日留存计算
* '3' 3日留存
* '4' 4日留存
* '5' 5日留存
* '6' 6日留存
* '7' 7日留存
* '15' 15日留存
* '30' 30日留存
*/
private $nodes = [1, 2, 3, 4, 5, 6, 7, 15, 30];
private $servers = ['1001' => ['opentime' => '2017-11-24 10:32:56']];
public function _initialize()
{
$this->lregister = new LRegister();
$this->llogin = new LLogin();
$this->model = new Retention;
}
/**
* 留存计算
*
* @return void
*/
public function doCompute()
{
//逆序计算留存
//
$this->computeReversed();
}
/**
* 逆序留存计算
*
* @return void
*/
public function computeReversed()
{
// 计算日期
$calcDate = date('Y-m-d', strtotime("-1 day"));
// 遍历服务器数组
foreach ($this->servers as $key => $info) {
$opentime = $info['opentime'];
// 遍历留存计算日期
foreach ($this->nodes as $day) {
//留存模型实例化
$model = new Retention;
//保存数组
//
$res = [];
//玩家注册日期和开服时间比较,如果注册日期大于开服日期,计算该节点用户留存
$regDate = date('Y-m-d', strtotime("-" . $day . " day"));
//开服日期
$open_date = date("Y-m-d", strtotime($opentime));
if (strtotime($regDate) >= strtotime($open_date)) {
if (1 === $day) {
//计算新注册人数及日活跃人数
$res['date'] = $regDate;
$res['DAU'] = $this->llogin->getDAU($regDate);
$res['register'] = $this->lregister->getRegTotal($regDate);
//保存昨天的新注册及日活跃人数
$model->isUpdate(false)->save($res);
//dump($model->getLastSql());
} else if (1 < $day) {
//计算注册日期开始,第 $day 天的留存数
$res['RET' . $day] = $this->llogin->getRET($regDate, $calcDate);
//保存注册日期开始,第 $day 天的留存数
$this->model->isUpdate(true)->save($res,['date'=>$regDate]);
//dump($model->getLastSql());
}
}
}
}
}
/**
* 顺序留存计算
*
* @return void
*/
public function computeInorder()
{
//不限时间
set_time_limit(0);
//开服日期
$opentime = '2017-11-24';
$today = date("Y-m-d");
//计算日期差值
$days = floor((strtotime($today) - strtotime($opentime)) / 86400);
$rtn = [];
//计算开服至今留存、活跃及注册人数
for ($x = 0; $x < $days; $x++) {
//保存数组
$res = [];
$time = strtotime($opentime) + 3600 * 24 * $x;
$regDate = date('Y-m-d', $time);
//保存日期
$res['date'] = $regDate;
$start_time = microtime(true);
foreach ($this->nodes as $day) {
//计算当日注册及活跃
if (1 == $day) {
//计算新注册人数及日活跃人数
$res['DAU'] = $this->llogin->getDAU($regDate);
$res['register'] = $this->lregister->getRegTotal($regDate);
} else {
//计算注册日期第 $day 天的留存率
$calcTime = strtotime($regDate) + 3600 * 24 * ($day - 1);
$calcDate = date('Y-m-d', $calcTime);
//前提留存计算日期小于今天
if ((strtotime($today) - 3600 * 24) >= $calcTime) {
$res['RET' . $day] = $this->llogin->getRET($regDate, $calcDate);
} else {
$res['RET' . $day] = null;
}
}
$res['create_time'] = date("Y-m-d H:i:s", time());
}
array_push($rtn, $res);
$end_time = microtime(true);
echo '循环执行时间为:' . ($end_time - $start_time) . ' s';
echo '<br />';
}
dump($rtn);
//保存所有日期节点的留存注册数据以及活跃率数据
$this->model->insertAll($rtn);
}
}
~~~
发现共用一个数据模型实例的时候,只更新修改一条数据。按如下方式修改之后,每次数据的新增及更新操作均实例化新的数据模型对象
~~~
<?php
namespace app\index\controller;
use app\index\model\LLogin;
use app\index\model\LRegister;
use app\index\model\Retention;
use think\Controller;
header("Content-type: text/html; charset=utf-8");
/**
* Cronret compute()方法由系统Command类命令行程序定期调用,实现用户留存信息计算
*/
class Cronret extends Controller
{
/*
* '1' 注册用户数,日活跃用户计算
* '2' 次日留存计算
* '3' 3日留存
* '4' 4日留存
* '5' 5日留存
* '6' 6日留存
* '7' 7日留存
* '15' 15日留存
* '30' 30日留存
*/
private $nodes = [1, 2, 3, 4, 5, 6, 7, 15, 30];
private $servers = ['1001' => ['opentime' => '2017-11-24 10:32:56']];
public function _initialize()
{
$this->lregister = new LRegister();
$this->llogin = new LLogin();
}
/**
* 留存计算
*
* @return void
*/
public function doCompute()
{
//逆序计算留存
//
$this->computeReversed();
}
/**
* 逆序留存计算
*
* @return void
*/
public function computeReversed()
{
// 计算日期
$calcDate = date('Y-m-d', strtotime("-1 day"));
// 遍历服务器数组
foreach ($this->servers as $key => $info) {
$opentime = $info['opentime'];
// 遍历留存计算日期
foreach ($this->nodes as $day) {
//留存模型实例化
$model = new Retention;
//保存数组
//
$res = [];
//玩家注册日期和开服时间比较,如果注册日期大于开服日期,计算该节点用户留存
$regDate = date('Y-m-d', strtotime("-" . $day . " day"));
//开服日期
$open_date = date("Y-m-d", strtotime($opentime));
if (strtotime($regDate) >= strtotime($open_date)) {
if (1 === $day) {
//计算新注册人数及日活跃人数
$res['date'] = $regDate;
$res['DAU'] = $this->llogin->getDAU($regDate);
$res['register'] = $this->lregister->getRegTotal($regDate);
//保存昨天的新注册及日活跃人数
$model->isUpdate(false)->save($res);
//dump($model->getLastSql());
} else if (1 < $day) {
//计算注册日期开始,第 $day 天的留存数
$res['RET' . $day] = $this->llogin->getRET($regDate, $calcDate);
//保存注册日期开始,第 $day 天的留存数
$model->isUpdate(true)->save($res,['date'=>$regDate]);
//dump($model->getLastSql());
}
}
}
}
}
/**
* 顺序留存计算
*
* @return void
*/
public function computeInorder()
{
//不限时间
set_time_limit(0);
//开服日期
$opentime = '2017-11-24';
$today = date("Y-m-d");
//计算日期差值
$days = floor((strtotime($today) - strtotime($opentime)) / 86400);
$rtn = [];
//计算开服至今留存、活跃及注册人数
for ($x = 0; $x < $days; $x++) {
//保存数组
$res = [];
$time = strtotime($opentime) + 3600 * 24 * $x;
$regDate = date('Y-m-d', $time);
//保存日期
$res['date'] = $regDate;
$start_time = microtime(true);
foreach ($this->nodes as $day) {
//计算当日注册及活跃
if (1 == $day) {
//计算新注册人数及日活跃人数
$res['DAU'] = $this->llogin->getDAU($regDate);
$res['register'] = $this->lregister->getRegTotal($regDate);
} else {
//计算注册日期第 $day 天的留存率
$calcTime = strtotime($regDate) + 3600 * 24 * ($day - 1);
$calcDate = date('Y-m-d', $calcTime);
//前提留存计算日期小于今天
if ((strtotime($today) - 3600 * 24) >= $calcTime) {
$res['RET' . $day] = $this->llogin->getRET($regDate, $calcDate);
} else {
$res['RET' . $day] = null;
}
}
$res['create_time'] = date("Y-m-d H:i:s", time());
}
array_push($rtn, $res);
$end_time = microtime(true);
echo '循环执行时间为:' . ($end_time - $start_time) . ' s';
echo '<br />';
}
dump($rtn);
//保存所有日期节点的留存注册数据以及活跃率数据
$model = new Retention;
$model->insertAll($rtn);
}
}
~~~
结果
~~~
array(3) {
["date"] => string(10) "2017-12-30"
["DAU"] => int(0)
["register"] => int(0)
}
string(174) "INSERT INTO `acc_dragon_retention` (`date` , `DAU` , `register` , `create_time` , `update_time`) VALUES ('2017-12-30' , 0 , 0 , '2017-12-31 12:36:18' , '2017-12-31 12:36:18')"
array(2) {
["RET2"] => int(0)
["date"] => string(10) "2017-12-29"
}
string(129) "UPDATE `acc_dragon_retention` SET `RET2`=0,`date`='2017-12-29',`update_time`='2017-12-31 12:36:18' WHERE `date` = '2017-12-29'"
array(2) {
["RET3"] => int(0)
["date"] => string(10) "2017-12-28"
}
string(129) "UPDATE `acc_dragon_retention` SET `RET3`=0,`date`='2017-12-28',`update_time`='2017-12-31 12:36:18' WHERE `date` = '2017-12-28'"
array(2) {
["RET4"] => int(0)
["date"] => string(10) "2017-12-27"
}
string(129) "UPDATE `acc_dragon_retention` SET `RET4`=0,`date`='2017-12-27',`update_time`='2017-12-31 12:36:18' WHERE `date` = '2017-12-27'"
array(2) {
["RET5"] => int(0)
["date"] => string(10) "2017-12-26"
}
string(129) "UPDATE `acc_dragon_retention` SET `RET5`=0,`date`='2017-12-26',`update_time`='2017-12-31 12:36:18' WHERE `date` = '2017-12-26'"
array(2) {
["RET6"] => int(0)
["date"] => string(10) "2017-12-25"
}
string(129) "UPDATE `acc_dragon_retention` SET `RET6`=0,`date`='2017-12-25',`update_time`='2017-12-31 12:36:18' WHERE `date` = '2017-12-25'"
array(2) {
["RET7"] => int(0)
["date"] => string(10) "2017-12-24"
}
string(129) "UPDATE `acc_dragon_retention` SET `RET7`=0,`date`='2017-12-24',`update_time`='2017-12-31 12:36:18' WHERE `date` = '2017-12-24'"
array(2) {
["RET15"] => int(0)
["date"] => string(10) "2017-12-16"
}
string(130) "UPDATE `acc_dragon_retention` SET `RET15`=0,`date`='2017-12-16',`update_time`='2017-12-31 12:36:18' WHERE `date` = '2017-12-16'"
array(2) {
["RET30"] => int(0)
["date"] => string(10) "2017-12-01"
}
string(130) "UPDATE `acc_dragon_retention` SET `RET30`=0,`date`='2017-12-01',`update_time`='2017-12-31 12:36:18' WHERE `date` = '2017-12-01'"
~~~