|
@@ -0,0 +1,235 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace Jiaruan;
|
|
|
+
|
|
|
+class DahuaUtil
|
|
|
+{
|
|
|
+ /*位操作*/
|
|
|
+ public static function getb($val, $pos)
|
|
|
+ {
|
|
|
+ //获取整数$val第$pos位的值
|
|
|
+ return (($val & 1 << $pos) > 0) ? 1 : 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function setb(&$val, $pos, $newVal)
|
|
|
+ {
|
|
|
+ //设置整数$val第$pos位的值 $newVal为0或1
|
|
|
+ if ($newVal) {//设置为1
|
|
|
+ $val |= (1 << $pos);
|
|
|
+ } else {//设置为0
|
|
|
+ $val &= ~(1 << $pos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function getBit($val, $posArr)
|
|
|
+ {
|
|
|
+ //$val整数 $posArr位置数组[1,2,3] 或 $posArr[0]='1-3'; $posArr = [0, 1, 2, 3]
|
|
|
+ //返回值 整数
|
|
|
+ if (strpos($posArr[0], '-')) {
|
|
|
+ $tmp = explode('-', $posArr[0], 2);
|
|
|
+ $posArr = range($tmp[0], $tmp[1]);
|
|
|
+ }
|
|
|
+ $ret = '';
|
|
|
+ foreach ($posArr as $pos) {
|
|
|
+ $ret = DahuaUtil::getb($val, $pos) . $ret;
|
|
|
+ }
|
|
|
+ return bindec($ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function setBit(&$val, $posArr, $newVal)
|
|
|
+ {
|
|
|
+ //$val 整数 旧值
|
|
|
+ //$posArr 数组 要更改的位 $posArr[0]='1-3'; $posArr = [0, 1, 2, 3]
|
|
|
+ //$newVal 整数 新值
|
|
|
+ if (strpos($posArr[0], '-')) {
|
|
|
+ $tmp = explode('-', $posArr[0], 2);
|
|
|
+ $posArr = range($tmp[0], $tmp[1]);
|
|
|
+ }
|
|
|
+ $ival = strrev(decbin($newVal));//反转下
|
|
|
+ $k = 0;
|
|
|
+ foreach ($posArr as $pos) {
|
|
|
+ if (!isset($ival[$k])) {
|
|
|
+ $ival[$k] = 0;
|
|
|
+ }
|
|
|
+ DahuaUtil::setb($val, $pos, $ival[$k]);
|
|
|
+ $k++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*位操作*/
|
|
|
+
|
|
|
+
|
|
|
+ public static function parseLocation($str)
|
|
|
+ {
|
|
|
+ $location_arr = explode(',', $str);
|
|
|
+
|
|
|
+ $location = [];
|
|
|
+ $location['locationState'] = $location_arr[0];
|
|
|
+ $lat_d = substr($location_arr[1], 0, 2);
|
|
|
+ $lat_m = substr($location_arr[1], 2);
|
|
|
+ $location['lat'] = $lat_d + $lat_m * 60;
|
|
|
+ $location['latType'] = $location_arr[2];
|
|
|
+ $lng_d = substr($location_arr[3], 0, 3);
|
|
|
+ $lng_m = substr($location_arr[3], 3);
|
|
|
+ $location['lng'] = $lng_d + $lng_m * 60;
|
|
|
+ $location['lngType'] = $location_arr[4];
|
|
|
+ return $location;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function rlog(...$args)
|
|
|
+ {
|
|
|
+ //函数参数是可变参数 使用前查下static开始的大写变量配置是否正确
|
|
|
+ //rlog('info', [1,2,3], $a = null, '[]', $this, false);
|
|
|
+ $args = func_get_args();
|
|
|
+// if (empty($args[0])) {
|
|
|
+// return;
|
|
|
+// }
|
|
|
+ static $LOG_CONSOLE = true;//是否输出到控制台 fpm需要为false cli可以为true
|
|
|
+ static $LOG_NAME = "dahua.log";//值为空时 不写入文件
|
|
|
+ static $LOG_SIZE = 128 * 1024 * 1024;//文件最大尺寸 大于这个尺寸时 会生成个后缀.old的文件
|
|
|
+
|
|
|
+ static $LOG_CACHE = false;//是否缓存日志内容 用于批量写入文件 如需强制刷新第一个参数传sync
|
|
|
+ static $CACHE_DURATION = 10;//缓存最大时间 秒
|
|
|
+ static $CACHE_SIZE = 1024;//缓存大小
|
|
|
+ static $cacheStartTime = 0;
|
|
|
+ static $cacheBuf = '';
|
|
|
+
|
|
|
+ static $LOG_TIMES = 10;//调用这个函数最大次数 超过次数或$logCount==1 会判断下文件大小 决定是否新生成文件
|
|
|
+ static $logCount = 0;
|
|
|
+
|
|
|
+ static $MAX_LEN = 5048;//数据不能超过这个 不然就截断了
|
|
|
+
|
|
|
+ $sync = false;//如果是true 使用$LOG_CACHE时会把数据保存到磁盘
|
|
|
+
|
|
|
+ $implicit0 = ['imsync', 'imtrace'];//这个函数的参数0 隐藏用法
|
|
|
+ $buf = '';
|
|
|
+ if (count($args) == 1 && $args[0] == "\n") {//只有换行时 不写入时间戳了
|
|
|
+ $buf = "\n";
|
|
|
+ } else {
|
|
|
+ $sync = strtolower($args[0]) == $implicit0[0];
|
|
|
+
|
|
|
+ $pid = '';//进程id
|
|
|
+ if (function_exists('posix_getpid')) {
|
|
|
+ $pid = ' ' . posix_getpid() . ' ';
|
|
|
+ }
|
|
|
+ $fileLine = '';//文件名:行号
|
|
|
+ {
|
|
|
+ $debug = debug_backtrace();
|
|
|
+ $backtrace = 0;
|
|
|
+ if (strpos($args[0], $implicit0[1]) === 0) {
|
|
|
+ $backtrace = intval(str_replace($implicit0[1], '', $args[0]));
|
|
|
+ unset($args[0]);
|
|
|
+ } else if ($sync) {
|
|
|
+ unset($args[0]);
|
|
|
+ }
|
|
|
+ $fileLine = ($pid == '' ? ' ' : '') . basename($debug[$backtrace]['file'])
|
|
|
+ . ':' . $debug[$backtrace]['line'] . '';
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ $allPara = '';
|
|
|
+ foreach ($args as $para) {
|
|
|
+ if (is_array($para)) {
|
|
|
+ $allPara .= json_encode($para) . ' ';
|
|
|
+ } else if (is_object($para)) {
|
|
|
+ if (method_exists($para, '__toString')) {
|
|
|
+ $allPara .= $para . ' ';
|
|
|
+ } else {
|
|
|
+ $allPara .= get_class($para) . json_encode($para) . ' ';
|
|
|
+ }
|
|
|
+ } else if (is_bool($para)) {
|
|
|
+ $allPara .= $para ? 'true ' : 'false ';
|
|
|
+ } else if (is_null($para)) {
|
|
|
+ $allPara .= 'null ';
|
|
|
+ } else {
|
|
|
+ $allPara .= $para . ' ';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $len = strlen($allPara);
|
|
|
+ if ($len > $MAX_LEN) {
|
|
|
+ $allPara = substr($allPara, 0, $MAX_LEN) . "({$len})......";
|
|
|
+ }
|
|
|
+
|
|
|
+ $buf = "[" . date("y-m-d H:i:s") . "{$pid}{$fileLine}]" . $allPara . "\n";
|
|
|
+ }
|
|
|
+
|
|
|
+ $logCount++;
|
|
|
+ if (!empty($LOG_NAME)) {
|
|
|
+ if ($LOG_CACHE) {
|
|
|
+ if ($cacheBuf == '') {
|
|
|
+ $cacheStartTime = time();
|
|
|
+ }
|
|
|
+ $cacheBuf .= $buf;
|
|
|
+ //超过缓存尺寸 或者 超过缓存时长 写缓存到文件
|
|
|
+ if (strlen($cacheBuf) > $CACHE_SIZE || time() - $cacheStartTime > $CACHE_DURATION) {
|
|
|
+ $cacheStartTime = time();
|
|
|
+ goto write;
|
|
|
+ } else {
|
|
|
+ if ($sync) {
|
|
|
+ goto write;
|
|
|
+ } else {
|
|
|
+ goto skipWrite;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $cacheBuf = $buf;
|
|
|
+ }
|
|
|
+ write: {
|
|
|
+ if ($logCount > 100) {//会有缓存
|
|
|
+ clearstatcache();
|
|
|
+ }
|
|
|
+ //超过尺寸后 删除旧文件 把新文件重命名为旧文件
|
|
|
+ if (($logCount == 1 || $logCount > $LOG_TIMES) && filesize($LOG_NAME) > $LOG_SIZE) {
|
|
|
+
|
|
|
+ //获取独占锁
|
|
|
+ $fp = fopen($LOG_NAME . '.lock', 'a');
|
|
|
+ $k = 0;
|
|
|
+ do {
|
|
|
+ $isLock = flocK($fp, LOCK_EX);
|
|
|
+ $k++;
|
|
|
+ if (!$isLock && $k > 1000) {
|
|
|
+ echo "lock 1000\n";
|
|
|
+ goto PUT;
|
|
|
+ }
|
|
|
+ } while (!$isLock);
|
|
|
+
|
|
|
+ //另外一个进程进入时 重新判断下
|
|
|
+ clearstatcache();
|
|
|
+ if (filesize($LOG_NAME) <= $LOG_SIZE) {
|
|
|
+ goto UN;
|
|
|
+ }
|
|
|
+
|
|
|
+ //删除旧文件和重命名文件
|
|
|
+ $oldLogName = $LOG_NAME . '.old';
|
|
|
+ if (file_exists($oldLogName)) {
|
|
|
+ if (!unlink($oldLogName)) {
|
|
|
+ echo "unlink err\n";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!rename($LOG_NAME, $oldLogName)) {
|
|
|
+ echo "rename err\n";
|
|
|
+ }
|
|
|
+
|
|
|
+ //解锁
|
|
|
+ UN:
|
|
|
+ flock($fp, LOCK_UN);
|
|
|
+ fclose($fp);
|
|
|
+
|
|
|
+
|
|
|
+ $logCount = 0;
|
|
|
+ }
|
|
|
+ PUT:
|
|
|
+ if (!file_put_contents($LOG_NAME, $cacheBuf, FILE_APPEND)) {
|
|
|
+ echo "file_put_contents err\n";
|
|
|
+ }
|
|
|
+ $cacheBuf = '';
|
|
|
+ }
|
|
|
+ skipWrite:{
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ($LOG_CONSOLE) {
|
|
|
+ echo $buf;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|