'int', 'flow_visitor_ip' => 'string', 'flow_location' => 'string', 'flow_source' => 'string', 'flow_browser' => 'string', 'flow_record_no' => 'string', 'flow_os'=>'string', 'flow_target'=>'string', 'flow_create_user_guid' => 'string', 'flow_create_time' => 'datetime', 'flow_update_time' => 'datetime', 'flow_update_user_guid' => 'string', 'flow_delete_time' => 'datetime', 'flow_delete_user_guid' => 'string', ]; // 开启自动写入时间戳字段 protected $autoWriteTimestamp = 'datetime'; // 创建时间 protected $createTime = 'flow_create_time'; // 修改时间 protected $updateTime = 'flow_update_time'; /** * 新增前 */ public static function onBeforeInsert(self $model): void { // self::checkRepeatData($model); // $model->completeCreateField(); } /** * 更新前 */ public static function onBeforeUpdate(self $model): void { // self::checkRepeatData($model); // $model->completeUpdateField(); } /** * 删除前 */ public static function onBeforeDelete(self $model): void { // $model->completeDeleteField(); } /** * @throws Throwable */ public function track($flow_target) { $res = []; //获取访问者ip $res['flow_visitor_ip'] = $this->getIp(); //获取访问者操作系统 $res['flow_os'] = $this->getOs(); //获取访问者浏览器 $res['flow_browser'] = $this->getBrowser(); //获取访问者地址 $res['flow_location'] = $this->getLocation(); //获取访问者来源 $res['flow_source'] = $this->getSource(); //生成记录号 $res['flow_record_no'] = $this->createRecordNumber(); //访问目的地 $res['flow_target'] = $this->getTarget($flow_target); $res['flow_create_time'] = date("Y-m-d H:i:s"); // return json($_SERVER); // return json($res); try { $this::create($res); }catch (Throwable $th){ throw $th; } } private function getTarget($flow_target):string { $url = $flow_target; // $res_url = explode('/',$url)[1]; $match_res_pool = [ 'index'=>'首页', 'about-intro-idx'=>'关于我们-厚德简介', 'about-env-idx-type'=>'关于我们-教学环境', 'about-history-idx'=>'关于我们-发展历程', 'signUp-signUp_introduction-idx-page'=>'招生报名-招生简介', 'signUp-signUp_introduction-details-id'=>'招生报名-招生简介-详情页', 'signUp-classes_intro-idx-page'=>'招生报名-班型介绍', 'signUp-classes_intro-details-id'=>'招生报名-班型介绍-详情页', 'signUp-enrol_aq-idx'=>'招生报名-招生回答', 'signUp-signup_way-idx'=>'招生报名-报名方式', 'teachers-idx'=>'师资力量', 'teachers-details-id'=>'师资力量-详情页', 'achievement-school_achievement-idx'=>'荣誉成绩-录取院校', 'achievement-joint_achievement-idx-page'=>'荣誉成绩-联考成绩', 'achievement-joint_achievement-details-id'=>'荣誉成绩-联考成绩-详情页', 'works-idx'=>'作品欣赏', 'news-idx-page'=>'艺考咨询', 'news-details-id'=>'艺考咨询', 'contactUs-contact_info-idx'=>'联系我们-联系方式', 'contactUs-signup-idx'=>'联系我们-在线报名', 'contactUs-leave_message-idx'=>'联系我们-用户留言', 'contactUs-join_apply-idx'=>'联系我们-合作加盟', ]; if(!isset($match_res_pool[$url])){ return '未知页面'; } return $match_res_pool[$url]; } private function createRecordNumber(): string { return date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT); } private function getSource(){ if(isset($_SERVER['HTTP_REFERER'])){ $colon_index = stripos($_SERVER['HTTP_REFERER'], ':'); $ds = '/'; $ds_count = 0; //冒号后斜杠的数量 for ($i = $colon_index + 1; $i < strlen($_SERVER['HTTP_REFERER']); $i++) { if ($_SERVER['HTTP_REFERER'][$i] != $ds) break; $ds_count++; } $url_data = explode('/', $_SERVER['HTTP_REFERER']); $url = ""; foreach ($url_data as $key => $val) { if ($key > $ds_count-1) $url .= $ds . $val; }; return explode('/',$url)[1]; } return '直接访问'; } private function getOs(): string { if (!empty($_SERVER['HTTP_USER_AGENT'])) { $OS = $_SERVER['HTTP_USER_AGENT']; if (preg_match('/win/i', $OS)) { $OS = 'window'; } elseif (preg_match('/mac/i', $OS)) { $OS = 'mac'; } elseif (preg_match('/linux/i', $OS)) { $OS = 'linux'; } elseif (preg_match('/unix/i', $OS)) { $OS = 'unix'; } elseif (preg_match('/bsd/i', $OS)) { $OS = 'bsd'; } else { $OS = '其他操作系统'; } return $OS; } else { return "获取访客操作系统信息失败!"; } } private function getBrowser() { if (isset($_SERVER["HTTP_USER_AGENT"])) { $user_agent = strtolower($_SERVER["HTTP_USER_AGENT"]); } else { return null; } $user_agent=strtolower($_SERVER["HTTP_USER_AGENT"]); // 固定检测 if (strrpos($user_agent, 'micromessenger')) { $user_bs = 'Weixin'; } elseif (strrpos($user_agent, 'qq')) { $user_bs = 'QQ'; } elseif (strrpos($user_agent, 'weibo')) { $user_bs = 'Weibo'; } elseif (strrpos($user_agent, 'alipayclient')) { $user_bs = 'Alipay'; } elseif (strrpos($user_agent, 'trident/7.0')) { $user_bs = 'IE11'; // 新版本IE优先,避免360等浏览器的兼容模式检测错误 } elseif (strrpos($user_agent, 'trident/6.0')) { $user_bs = 'IE10'; } elseif (strrpos($user_agent, 'trident/5.0')) { $user_bs = 'IE9'; } elseif (strrpos($user_agent, 'trident/4.0')) { $user_bs = 'IE8'; } elseif (strrpos($user_agent, 'msie 7.0')) { $user_bs = 'IE7'; } elseif (strrpos($user_agent, 'msie 6.0')) { $user_bs = 'IE6'; } elseif (strrpos($user_agent, 'edg')) { $user_bs = 'Edge'; } elseif (strrpos($user_agent, 'firefox')) { $user_bs = 'Firefox'; } elseif (strrpos($user_agent, 'chrome') || strrpos($user_agent, 'android')) { $user_bs = 'Chrome'; } elseif (strrpos($user_agent, 'safari')) { $user_bs = 'Safari'; } elseif (strrpos($user_agent, 'mj12bot')) { $user_bs = 'MJ12bot'; } else { $user_bs = '其他浏览器'; } return $user_bs; } private function getIp() { if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP") , "unknown")) { $ip = getenv("HTTP_CLIENT_IP"); } else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR") , "unknown")) { $ip = getenv("HTTP_X_FORWARDED_FOR"); } else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR") , "unknown")) { $ip = getenv("REMOTE_ADDR"); } else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown")) { $ip = $_SERVER['REMOTE_ADDR']; } else { $ip = "unknown"; } return $ip; } private function getLocation($ip = '') { empty($ip) && $ip = $this->getIp(); $location = ''; if ($ip == "127.0.0.1") return ("本机地址"); $bLocalIp = !filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE); if($bLocalIp)return '局域网IP'; try { $api = "https://www.fkcoder.com/ip?ip=$ip"; //请求新浪ip地址库 $json = @file_get_contents($api); $res = json_decode($json, true); $location = $res['country'].$res['province'].$res['city']; return $location; }catch (Throwable $th){ return 'ip获取异常'; } } }