DahuaUtil.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. <?php
  2. namespace Jiaruan;
  3. class DahuaUtil
  4. {
  5. /*位操作*/
  6. function getb($val, $pos)
  7. {
  8. //获取整数$val第$pos位的值
  9. return (($val & 1 << $pos) > 0) ? 1 : 0;
  10. }
  11. function setb(&$val, $pos, $newVal)
  12. {
  13. //设置整数$val第$pos位的值 $newVal为0或1
  14. if ($newVal) {//设置为1
  15. $val |= (1 << $pos);
  16. } else {//设置为0
  17. $val &= ~(1 << $pos);
  18. }
  19. }
  20. function getBit($val, $posArr)
  21. {
  22. //$val整数 $posArr位置数组[1,2,3] 或 $posArr[0]='1-3'; $posArr = [0, 1, 2, 3]
  23. //返回值 整数
  24. if (strpos($posArr[0], '-')) {
  25. $tmp = explode('-', $posArr[0], 2);
  26. $posArr = range($tmp[0], $tmp[1]);
  27. }
  28. $ret = '';
  29. foreach ($posArr as $pos) {
  30. $ret = DahuaUtil::getb($val, $pos) . $ret;
  31. }
  32. return bindec($ret);
  33. }
  34. function setBit(&$val, $posArr, $newVal)
  35. {
  36. //$val 整数 旧值
  37. //$posArr 数组 要更改的位 $posArr[0]='1-3'; $posArr = [0, 1, 2, 3]
  38. //$newVal 整数 新值
  39. if (strpos($posArr[0], '-')) {
  40. $tmp = explode('-', $posArr[0], 2);
  41. $posArr = range($tmp[0], $tmp[1]);
  42. }
  43. $ival = strrev(decbin($newVal));//反转下
  44. $k = 0;
  45. foreach ($posArr as $pos) {
  46. if (!isset($ival[$k])) {
  47. $ival[$k] = 0;
  48. }
  49. DahuaUtil::setb($val, $pos, $ival[$k]);
  50. $k++;
  51. }
  52. }
  53. /*位操作*/
  54. function parseLocation($str)
  55. {
  56. $location_arr = explode(',', $str);
  57. $location = [];
  58. $location['locationState'] = $location_arr[0];
  59. $lat_d = substr($location_arr[1], 0, 2);
  60. $lat_m = substr($location_arr[1], 2);
  61. $location['lat'] = $lat_d + $lat_m * 60;
  62. $location['latType'] = $location_arr[2];
  63. $lng_d = substr($location_arr[3], 0, 3);
  64. $lng_m = substr($location_arr[3], 3);
  65. $location['lng'] = $lng_d + $lng_m * 60;
  66. $location['lngType'] = $location_arr[4];
  67. return $location;
  68. }
  69. function rlog(...$args)
  70. {
  71. //函数参数是可变参数 使用前查下static开始的大写变量配置是否正确
  72. //rlog('info', [1,2,3], $a = null, '[]', $this, false);
  73. $args = func_get_args();
  74. //if (empty($args[0])) {
  75. //return;
  76. //}
  77. static $LOG_CONSOLE = false;//是否输出到控制台 fpm需要为false cli可以为true
  78. static $LOG_NAME = "dahua.log";//值为空时 不写入文件
  79. static $LOG_SIZE = 1024 * 1024 * 1024;//文件最大尺寸 大于这个尺寸时 会生成个后缀.old的文件
  80. static $LOG_CACHE = true;//是否缓存日志内容 用于批量写入文件 如需强制刷新第一个参数传sync
  81. static $CACHE_DURATION = 30;//缓存最大时间 秒
  82. static $CACHE_SIZE = 1024 * 1024 * 1;//缓存大小
  83. static $cacheStartTime = 0;
  84. static $cacheBuf = '';
  85. static $LOG_TIMES = 10;//调用这个函数最大次数 超过次数或$logCount==1 会判断下文件大小 决定是否新生成文件
  86. static $logCount = 0;
  87. static $MAX_LEN = 5048;//数据不能超过这个 不然就截断了
  88. $sync = false;//如果是true 使用$LOG_CACHE时会把数据保存到磁盘
  89. $implicit0 = ['imsync', 'imtrace'];//这个函数的参数0 隐藏用法
  90. $buf = '';
  91. if (count($args) == 1 && $args[0] == "\n") {//只有换行时 不写入时间戳了
  92. $buf = "\n";
  93. } else {
  94. $sync = strtolower($args[0]) == $implicit0[0];
  95. $pid = '';//进程id
  96. if (function_exists('posix_getpid')) {
  97. $pid = ' ' . posix_getpid() . ' ';
  98. }
  99. $fileLine = '';//文件名:行号
  100. {
  101. $debug = debug_backtrace();
  102. $backtrace = 0;
  103. if (strpos($args[0], $implicit0[1]) === 0) {
  104. $backtrace = intval(str_replace($implicit0[1], '', $args[0]));
  105. unset($args[0]);
  106. } else if ($sync) {
  107. unset($args[0]);
  108. }
  109. $fileLine = ($pid == '' ? ' ' : '') . basename($debug[$backtrace]['file'])
  110. . ':' . $debug[$backtrace]['line'] . '';
  111. }
  112. $allPara = '';
  113. foreach ($args as $para) {
  114. if (is_array($para)) {
  115. $allPara .= json_encode($para) . ' ';
  116. } else if (is_object($para)) {
  117. if (method_exists($para, '__toString')) {
  118. $allPara .= $para . ' ';
  119. } else {
  120. $allPara .= get_class($para) . json_encode($para) . ' ';
  121. }
  122. } else if (is_bool($para)) {
  123. $allPara .= $para ? 'true ' : 'false ';
  124. } else if (is_null($para)) {
  125. $allPara .= 'null ';
  126. } else {
  127. $allPara .= $para . ' ';
  128. }
  129. }
  130. $len = strlen($allPara);
  131. if ($len > $MAX_LEN) {
  132. $allPara = substr($allPara, 0, $MAX_LEN) . "({$len})......";
  133. }
  134. $buf = "[" . date("y-m-d H:i:s") . "{$pid}{$fileLine}]" . $allPara . "\n";
  135. }
  136. $logCount++;
  137. if (!empty($LOG_NAME)) {
  138. if ($LOG_CACHE) {
  139. if ($cacheBuf == '') {
  140. $cacheStartTime = time();
  141. }
  142. $cacheBuf .= $buf;
  143. //超过缓存尺寸 或者 超过缓存时长 写缓存到文件
  144. if (strlen($cacheBuf) > $CACHE_SIZE || time() - $cacheStartTime > $CACHE_DURATION) {
  145. $cacheStartTime = time();
  146. goto write;
  147. } else {
  148. if ($sync) {
  149. goto write;
  150. } else {
  151. goto skipWrite;
  152. }
  153. }
  154. } else {
  155. $cacheBuf = $buf;
  156. }
  157. write: {
  158. if ($logCount > 100) {
  159. clearstatcache();
  160. }
  161. //超过尺寸后 删除旧文件 把新文件重命名为旧文件 多进程同时操作 加锁
  162. if (($logCount == 1 || $logCount > $LOG_TIMES) && filesize($LOG_NAME) > $LOG_SIZE) {
  163. //获取独占锁
  164. $fp = fopen($LOG_NAME . '.lock', 'a');
  165. $k = 0;
  166. do {
  167. $isLock = flocK($fp, LOCK_EX);
  168. $k++;
  169. if (!$isLock && $k > 1000) {
  170. echo "lock 1000\n";
  171. goto PUT;
  172. }
  173. } while (!$isLock);
  174. //另外一个进程进入时 重新判断下
  175. clearstatcache();
  176. if (filesize($LOG_NAME) <= $LOG_SIZE) {
  177. goto UN;
  178. }
  179. $oldLogName = $LOG_NAME . '.old';
  180. if (file_exists($oldLogName)) {
  181. if (!unlink($oldLogName)) {
  182. echo "unlink err\n";
  183. }
  184. }
  185. if (!rename($LOG_NAME, $oldLogName)) {
  186. echo "rename err\n";
  187. }
  188. //解锁
  189. UN:
  190. flock($fp, LOCK_UN);
  191. fclose($fp);
  192. $logCount = 0;
  193. }
  194. PUT:
  195. if (!file_put_contents($LOG_NAME, $cacheBuf, FILE_APPEND)) {
  196. echo "file_put_contents err\n";
  197. }
  198. $cacheBuf = '';
  199. }
  200. skipWrite:{
  201. }
  202. }
  203. if ($LOG_CONSOLE) {
  204. echo $buf;
  205. }
  206. }
  207. }