原型
~~~
<?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'"
~~~