ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
原型 ~~~ <?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'" ~~~