common.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. <?php
  2. use app\common\server\ConfigServer;
  3. use app\common\server\UrlServer;
  4. use think\facade\Db;
  5. use app\common\model\user\User;
  6. use app\common\model\goods\Goods;
  7. use think\facade\Log;
  8. use think\facade\Validate;
  9. /**
  10. * Notes: 生成随机长度字符串
  11. * @param $length
  12. * @author FZR(2021/1/28 10:36)
  13. * @return string|null
  14. */
  15. function getRandChar($length)
  16. {
  17. $str = null;
  18. $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
  19. $max = strlen($strPol) - 1;
  20. for ($i = 0;
  21. $i < $length;
  22. $i++) {
  23. $str .= $strPol[rand(0, $max)];
  24. }
  25. return $str;
  26. }
  27. /**
  28. * Notes: 生成密码
  29. * @param $plaintext
  30. * @param $salt
  31. * @author FZR(2021/1/28 15:30)
  32. * @return string
  33. */
  34. function generatePassword($plaintext, $salt)
  35. {
  36. $salt = md5('y' . $salt . 'x');
  37. $salt .= '2021';
  38. return md5($plaintext . $salt);
  39. }
  40. /*
  41. * 导出数据到日志文件
  42. * */
  43. function outFileLog($data,$filename='log',$title='data'){
  44. file_put_contents(runtime_path() . 'log/'.$filename.'.txt', PHP_EOL .date('Y-m-d h:i:s', time()).'~'.$title.':' . json_encode($data,JSON_UNESCAPED_UNICODE), FILE_APPEND);
  45. }
  46. /**
  47. * Notes: 大写字母
  48. * @author 段誉(2021/4/15 15:55)
  49. * @return array
  50. */
  51. function getCapital()
  52. {
  53. return range('A','Z');
  54. }
  55. /**
  56. * 线性结构转换成树形结构
  57. * @param array $data 线性结构数组
  58. * @param string $sub_key_name 自动生成子数组名
  59. * @param string $id_name 数组id名
  60. * @param string $parent_id_name 数组祖先id名
  61. * @param int $parent_id 此值请勿给参数
  62. * @return array
  63. */
  64. function linear_to_tree($data, $sub_key_name = 'sub', $id_name = 'id', $parent_id_name = 'pid', $parent_id = 0)
  65. {
  66. $tree = [];
  67. foreach ($data as $row) {
  68. if ($row[$parent_id_name] == $parent_id) {
  69. $temp = $row;
  70. $temp[$sub_key_name] = linear_to_tree($data, $sub_key_name, $id_name, $parent_id_name, $row[$id_name]);
  71. $tree[] = $temp;
  72. }
  73. }
  74. return $tree;
  75. }
  76. /**
  77. * User: 意象信息科技 lr
  78. * Desc: 下载文件
  79. * @param $url 文件url
  80. * @param $save_dir 保存目录
  81. * @param $file_name 文件名
  82. * @return string
  83. */
  84. function download_file($url, $save_dir, $file_name)
  85. {
  86. if (!file_exists($save_dir)) {
  87. mkdir($save_dir, 0775, true);
  88. }
  89. $file_src = $save_dir . $file_name;
  90. file_exists($file_src) && unlink($file_src);
  91. $ch = curl_init();
  92. curl_setopt($ch, CURLOPT_URL, $url);
  93. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  94. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
  95. // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  96. $file = curl_exec($ch);
  97. curl_close($ch);
  98. $resource = fopen($file_src, 'a');
  99. fwrite($resource, $file);
  100. fclose($resource);
  101. if (filesize($file_src) == 0) {
  102. unlink($file_src);
  103. return '';
  104. }
  105. return $file_src;
  106. }
  107. /**
  108. * 生成会员码
  109. * @return 会员码
  110. */
  111. function create_user_sn($prefix = '', $length = 8)
  112. {
  113. $rand_str = '';
  114. for ($i = 0; $i < $length; $i++) {
  115. $rand_str .= mt_rand(0, 9);
  116. }
  117. $sn = $prefix . $rand_str;
  118. $user = User::where(['sn' => $sn])->findOrEmpty();
  119. if (!$user->isEmpty()) {
  120. return create_user_sn($prefix, $length);
  121. }
  122. return $sn;
  123. }
  124. //生成用户邀请码
  125. function generate_invite_code()
  126. {
  127. $letter_all = range('A', 'Z');
  128. shuffle($letter_all);
  129. //排除I、O字母
  130. $letter_array = array_diff($letter_all, ['I', 'O', 'D']);
  131. //排除1、0
  132. $num_array = range('2', '9');
  133. shuffle($num_array);
  134. $pattern = array_merge($num_array, $letter_array, $num_array);
  135. shuffle($pattern);
  136. $pattern = array_values($pattern);
  137. $code = '';
  138. for ($i = 0; $i < 6; $i++) {
  139. $code .= $pattern[mt_rand(0, count($pattern) - 1)];
  140. }
  141. $code = strtoupper($code);
  142. $check = User::where('distribution_code', $code)->findOrEmpty();
  143. if (!$check->isEmpty()) {
  144. return generate_invite_code();
  145. }
  146. return $code;
  147. }
  148. /**
  149. * User: 意象信息科技 lr
  150. * Desc: 数组成功拼装
  151. * @param string $msg
  152. * @param array $data
  153. * @param int $code
  154. * @param int $show
  155. * @return array
  156. */
  157. function data_success($msg = '', $data = [], $code = 1, $show = 1)
  158. {
  159. $result = [
  160. 'code' => $code,
  161. 'msg' => $msg,
  162. 'data' => $data,
  163. 'show' => $show,
  164. ];
  165. return $result;
  166. }
  167. /**
  168. * User: 意象信息科技 lr
  169. * Desc: 组装失败数据
  170. * @param string $msg
  171. * @param array $data
  172. * @param int $code
  173. * @param int $show
  174. * @return array
  175. */
  176. function data_error($msg = '', $data = [], $code = 0, $show = 1)
  177. {
  178. $result = [
  179. 'code' => $code,
  180. 'msg' => $msg,
  181. 'data' => $data,
  182. 'show' => $show,
  183. ];
  184. return $result;
  185. }
  186. /**
  187. * User: 意象信息科技 cjh
  188. * Desc: 返回是否有下一页
  189. * @param $count (总记录数)
  190. * @param $page (当前页码)
  191. * @param $size (每页记录数)
  192. * @return int
  193. */
  194. function is_more($count, $page, $size)
  195. {
  196. $more = 0;
  197. $last_page = ceil($count / $size); //总页数、也是最后一页
  198. if ($last_page && $last_page > $page) {
  199. $more = 1;
  200. }
  201. return $more;
  202. }
  203. /**
  204. * User: 意象信息科技 lr
  205. * Desc:生成密码密文
  206. * @param $plaintext string 明文
  207. * @param $salt string 密码盐
  208. * @return string
  209. */
  210. function create_password($plaintext, $salt)
  211. {
  212. $salt = md5('y' . $salt . 'x');
  213. $salt .= '2021';
  214. return md5($plaintext . $salt);
  215. }
  216. /**
  217. * User: 意象信息科技 mjf
  218. * Desc: 用时间生成订单编号
  219. * @param $table
  220. * @param $field
  221. * @param string $prefix
  222. * @param int $rand_suffix_length
  223. * @param array $pool
  224. * @return string
  225. * @throws \think\db\exception\DataNotFoundException
  226. * @throws \think\db\exception\DbException
  227. * @throws \think\db\exception\ModelNotFoundException
  228. */
  229. function createSn($table, $field, $prefix = '', $rand_suffix_length = 4, $pool = [])
  230. {
  231. $suffix = '';
  232. for ($i = 0; $i < $rand_suffix_length; $i++) {
  233. if (empty($pool)) {
  234. $suffix .= rand(0, 9);
  235. } else {
  236. $suffix .= $pool[array_rand($pool)];
  237. }
  238. }
  239. $sn = $prefix . date('YmdHis') . $suffix;
  240. if (Db::name($table)->where($field, $sn)->find()) {
  241. return createSn($table, $field, $prefix, $rand_suffix_length, $pool);
  242. }
  243. return $sn;
  244. }
  245. /**
  246. * User: 意象信息科技 lr
  247. * Desc: 表单多维数据转换
  248. * 例:
  249. * 转换前:{"x":0,"a":[1,2,3],"b":[11,22,33],"c":[111,222,3333,444],"d":[1111,2222,3333]}
  250. * 转换为:[{"a":1,"b":11,"c":111,"d":1111},{"a":2,"b":22,"c":222,"d":2222},{"a":3,"b":33,"c":3333,"d":3333}]
  251. * @param $arr array 表单二维数组
  252. * @param $fill boolean fill为false,返回数据长度取最短,反之取最长,空值自动补充
  253. * @return array
  254. */
  255. function form_to_linear($arr, $fill = false)
  256. {
  257. $keys = [];
  258. $count = $fill ? 0 : PHP_INT_MAX;
  259. foreach ($arr as $k => $v) {
  260. if (is_array($v)) {
  261. $keys[] = $k;
  262. $count = $fill ? max($count, count($v)) : min($count, count($v));
  263. }
  264. }
  265. if (empty($keys)) {
  266. return [];
  267. }
  268. $data = [];
  269. for ($i = 0; $i < $count; $i++) {
  270. foreach ($keys as $v) {
  271. $data[$i][$v] = isset($arr[$v][$i]) ? $arr[$v][$i] : null;
  272. }
  273. }
  274. return $data;
  275. }
  276. /**
  277. * note 生成验证码
  278. * @param int $length 验证码长度
  279. * @return string
  280. */
  281. function create_sms_code($length = 4)
  282. {
  283. $code = '';
  284. for ($i = 0; $i < $length; $i++) {
  285. $code .= rand(0, 9);
  286. }
  287. return $code;
  288. }
  289. /**
  290. * 生成商品编码
  291. * 8位
  292. */
  293. function create_goods_code($shop_id)
  294. {
  295. $code = mt_rand(10000000, 99999999);
  296. $goods = Goods::where([
  297. 'code' => $code,
  298. 'shop_id' => $shop_id,
  299. 'del' => 0
  300. ])->findOrEmpty();
  301. if($goods->isEmpty()) {
  302. return $code;
  303. }
  304. create_goods_code($shop_id);
  305. }
  306. /**
  307. * 图片去除域名
  308. */
  309. function clearDomain($x)
  310. {
  311. if(is_array($x)) {
  312. $newX = [];
  313. foreach($x as $v) {
  314. $newX[] = trim(UrlServer::setFileUrl($v));
  315. }
  316. return $newX;
  317. }
  318. return trim(UrlServer::setFileUrl($x));
  319. }
  320. /*
  321. * 生成优惠券码 排除1、0、I、O相似的数字和字母
  322. */
  323. function create_coupon_code()
  324. {
  325. $letter_all = range('A', 'Z');
  326. shuffle($letter_all);
  327. //排除I、O字母
  328. $letter_array = array_diff($letter_all, ['I', 'O']);
  329. //随机获取四位字母
  330. $letter = array_rand(array_flip($letter_array), 4);
  331. //排除1、0
  332. $num_array = range('2', '9');
  333. shuffle($num_array);
  334. //获取随机六位数字
  335. $num = array_rand(array_flip($num_array), 6);
  336. $code = implode('', array_merge($letter, $num));
  337. do {
  338. $exist_code =\app\common\model\coupon\CouponList::where(['del' => 0, 'coupon_code' => $code])->find();
  339. } while ($exist_code);
  340. return $code;
  341. }
  342. /**
  343. * 浮点数去除无效的0
  344. */
  345. function clearZero($float)
  346. {
  347. if($float == intval($float)) {
  348. return intval($float);
  349. }else if($float == sprintf('%.1f', $float)) {
  350. return sprintf('%.1f', $float);
  351. }
  352. return $float;
  353. }
  354. /**
  355. * 是否在cli模式
  356. */
  357. if (!function_exists('is_cli')) {
  358. function is_cli()
  359. {
  360. return preg_match("/cli/i", php_sapi_name()) ? true : false;
  361. }
  362. }
  363. function real_path()
  364. {
  365. if (substr(strtolower(PHP_OS), 0, 3) == 'win') {
  366. $ini = ini_get_all();
  367. $path = $ini['extension_dir']['local_value'];
  368. $php_path = str_replace('\\', '/', $path);
  369. $php_path = str_replace(array('/ext/', '/ext'), array('/', '/'), $php_path);
  370. $real_path = $php_path . 'php.exe';
  371. } else {
  372. $real_path = PHP_BINDIR . '/php';
  373. }
  374. if (strpos($real_path, 'ephp.exe') !== FALSE) {
  375. $real_path = str_replace('ephp.exe', 'php.exe', $real_path);
  376. }
  377. return $real_path;
  378. }
  379. /**
  380. * 是否为移动端
  381. */
  382. function is_mobile()
  383. {
  384. if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
  385. return true;
  386. }
  387. if (isset($_SERVER['HTTP_VIA'])) {
  388. return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
  389. }
  390. if (isset($_SERVER['HTTP_USER_AGENT'])) {
  391. $clientkeywords = array('nokia', 'sony', 'ericsson', 'mot', 'samsung', 'htc', 'sgh', 'lg', 'sharp', 'sie-', 'philips', 'panasonic', 'alcatel', 'lenovo', 'iphone', 'ipod', 'blackberry', 'meizu', 'android', 'netfront', 'symbian', 'ucweb', 'windowsce', 'palm', 'operamini', 'operamobi', 'openwave', 'nexusone', 'cldc', 'midp', 'wap', 'mobile');
  392. if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
  393. return true;
  394. }
  395. }
  396. if (isset($_SERVER['HTTP_ACCEPT'])) {
  397. if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'textml') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'textml')))) {
  398. return true;
  399. }
  400. }
  401. return false;
  402. }
  403. /**
  404. * Notes:判断文件是否存在(远程和本地文件)
  405. * @param $file string 完整的文件链接
  406. * @return bool
  407. */
  408. function check_file_exists($file)
  409. {
  410. //远程文件
  411. if ('http' == strtolower(substr($file, 0, 4))) {
  412. $header = get_headers($file, true);
  413. return isset($header[0]) && (strpos($header[0], '200') || strpos($header[0], '304'));
  414. } else {
  415. return file_exists($file);
  416. }
  417. }
  418. /**
  419. * 将图片切成圆角
  420. */
  421. function rounded_corner($src_img)
  422. {
  423. $w = imagesx($src_img);//微信头像宽度 正方形的
  424. $h = imagesy($src_img);//微信头像宽度 正方形的
  425. $w = min($w, $h);
  426. $h = $w;
  427. $img = imagecreatetruecolor($w, $h);
  428. //这一句一定要有
  429. imagesavealpha($img, true);
  430. //拾取一个完全透明的颜色,最后一个参数127为全透明
  431. $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
  432. imagefill($img, 0, 0, $bg);
  433. $r = $w / 2; //圆半径
  434. // $y_x = $r; //圆心X坐标
  435. // $y_y = $r; //圆心Y坐标
  436. for ($x = 0; $x < $w; $x++) {
  437. for ($y = 0; $y < $h; $y++) {
  438. $rgbColor = imagecolorat($src_img, $x, $y);
  439. if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
  440. imagesetpixel($img, $x, $y, $rgbColor);
  441. }
  442. }
  443. }
  444. unset($src_img);
  445. return $img;
  446. }
  447. /**
  448. * Notes:去掉名称中的表情
  449. * @param $str
  450. * @return string|string[]|null
  451. * @author: cjhao 2021/3/29 15:56
  452. */
  453. function filterEmoji($str)
  454. {
  455. $str = preg_replace_callback(
  456. '/./u',
  457. function (array $match) {
  458. return strlen($match[0]) >= 4 ? '' : $match[0];
  459. },
  460. $str);
  461. return $str;
  462. }
  463. /***
  464. * 生成海报自动适应标题
  465. * @param $size
  466. * @param int $angle
  467. * @param $fontfile
  468. * @param $string
  469. * @param $width
  470. * @param $height
  471. * @param $bg_height
  472. * @return string
  473. */
  474. function auto_adapt($size, $angle = 0, $fontfile, $string, $width, $height, $bg_height)
  475. {
  476. $content = "";
  477. // 将字符串拆分成一个个单字 保存到数组 letter 中
  478. for ($i = 0; $i < mb_strlen($string); $i++) {
  479. $letters[] = mb_substr($string, $i, 1);
  480. }
  481. foreach ($letters as $letter) {
  482. $str = $content . " " . $letter;
  483. $box = imagettfbbox($size, $angle, $fontfile, $str);
  484. $total_height = $box[1] + $height;
  485. if ($bg_height[1] - $total_height < $size) {
  486. break;
  487. }
  488. //右下角X位置,判断拼接后的字符串是否超过预设的宽度
  489. if (($box[2] > $width) && ($content !== "")) {
  490. if ($bg_height[1] - $total_height < $size * 2) {
  491. break;
  492. }
  493. $content .= "\n";
  494. }
  495. $content .= $letter;
  496. }
  497. return $content;
  498. }
  499. /**
  500. * Notes:生成一个范围内的随机浮点数
  501. * @param int $min 最小值
  502. * @param int $max 最大值
  503. * @return float|int 返回随机数
  504. */
  505. function random_float($min = 0, $max = 1)
  506. {
  507. return $min + mt_rand() / mt_getrandmax() * ($max - $min);
  508. }
  509. /**
  510. * Notes: 获取文件扩展名
  511. * @param $file
  512. * @author 段誉(2021/7/7 18:03)
  513. * @return mixed
  514. */
  515. if (!function_exists('get_extension')) {
  516. function get_extension($file)
  517. {
  518. return pathinfo($file, PATHINFO_EXTENSION);
  519. }
  520. }
  521. /**
  522. * Notes: 遍历指定目录下的文件(目标目录,排除文件)
  523. * @param $dir 目标文件
  524. * @param string $exclude_file 要排除的文件
  525. * @param string $target_suffix 指定后缀
  526. * @author 段誉(2021/7/7 18:04)
  527. * @return array|bool
  528. */
  529. if (!function_exists('get_scandir')) {
  530. function get_scandir($dir, $exclude_file = '', $target_suffix = '')
  531. {
  532. if (!file_exists($dir)) {
  533. return [];
  534. }
  535. if (empty(trim($dir))) {
  536. return false;
  537. }
  538. $files = scandir($dir);
  539. $res = [];
  540. foreach ($files as $item) {
  541. if ($item == "." || $item == ".." || $item == $exclude_file) {
  542. continue;
  543. }
  544. if (!empty($target_suffix)) {
  545. if (get_extension($item) == $target_suffix) {
  546. $res[] = $item;
  547. }
  548. } else {
  549. $res[] = $item;
  550. }
  551. }
  552. if (empty($item)) {
  553. return false;
  554. }
  555. return $res;
  556. }
  557. }
  558. /**
  559. * Notes: 解压压缩包
  560. * @param $file 压缩包路径
  561. * @param $save_dir 保存路径
  562. * @author 段誉(2021/7/7 18:11)
  563. * @return bool
  564. */
  565. if (!function_exists('unzip')) {
  566. function unzip($file, $save_dir)
  567. {
  568. if (!file_exists($file)) {
  569. return false;
  570. }
  571. $zip = new \ZipArchive();
  572. if ($zip->open($file) !== TRUE) {//中文文件名要使用ANSI编码的文件格式
  573. return false;
  574. }
  575. $zip->extractTo($save_dir);
  576. $zip->close();
  577. return true;
  578. }
  579. }
  580. /**
  581. * Notes: 删除目标目录
  582. * @param $path
  583. * @param $delDir
  584. * @author 段誉(2021/7/7 18:19)
  585. * @return bool
  586. */
  587. if (!function_exists('del_target_dir')) {
  588. function del_target_dir($path, $delDir)
  589. {
  590. //没找到,不处理
  591. if (!file_exists($path)) {
  592. return false;
  593. }
  594. $handle = opendir($path);
  595. if ($handle) {
  596. while (false !== ($item = readdir($handle))) {
  597. if ($item != "." && $item != "..") {
  598. if (is_dir("$path/$item")) {
  599. del_target_dir("$path/$item", $delDir);
  600. } else {
  601. unlink("$path/$item");
  602. }
  603. }
  604. }
  605. closedir($handle);
  606. if ($delDir) {
  607. return rmdir($path);
  608. }
  609. } else {
  610. if (file_exists($path)) {
  611. return unlink($path);
  612. }
  613. return false;
  614. }
  615. }
  616. }
  617. /**
  618. * Notes: 获取本地版本数据
  619. * @return mixed
  620. * @author 段誉(2021/7/7 18:18)
  621. */
  622. if (!function_exists('local_version')) {
  623. function local_version()
  624. {
  625. if(!file_exists('./upgrade/')) {
  626. // 若文件夹不存在,先创建文件夹
  627. mkdir('./upgrade/', 0777, true);
  628. }
  629. if(!file_exists('./upgrade/version.json')) {
  630. // 获取本地版本号
  631. $version = config('project.version');
  632. $data = ['version' => $version];
  633. $src = './upgrade/version.json';
  634. // 新建文件
  635. file_put_contents($src, json_encode($data, JSON_UNESCAPED_UNICODE));
  636. }
  637. $json_string = file_get_contents('./upgrade/version.json');
  638. // 用参数true把JSON字符串强制转成PHP数组
  639. $data = json_decode($json_string, true);
  640. return $data;
  641. }
  642. }
  643. /**
  644. * Notes: 获取ip
  645. * @author 段誉(2021/7/9 10:19)
  646. * @return array|false|mixed|string
  647. */
  648. if (!function_exists('get_client_ip')) {
  649. function get_client_ip()
  650. {
  651. if (!isset($_SERVER)) {
  652. return getenv('SERVER_ADDR');
  653. }
  654. if($_SERVER['SERVER_ADDR']) {
  655. return $_SERVER['SERVER_ADDR'];
  656. }
  657. return $_SERVER['LOCAL_ADDR'];
  658. }
  659. }
  660. /**
  661. * @notes 友好时间提示
  662. * @param $time
  663. * @return false|string
  664. * @author 段誉
  665. * @date 2022/5/6 9:45
  666. */
  667. function friend_date($time)
  668. {
  669. if (empty($time)) {
  670. return false;
  671. }
  672. $d = time() - intval($time);
  673. $ld = $time - mktime(0, 0, 0, 0, 0, date('Y')); //年
  674. $md = $time - mktime(0, 0, 0, date('m'), 0, date('Y')); //月
  675. $byd = $time - mktime(0, 0, 0, date('m'), date('d') - 2, date('Y')); //前天
  676. $yd = $time - mktime(0, 0, 0, date('m'), date('d') - 1, date('Y')); //昨天
  677. $dd = $time - mktime(0, 0, 0, date('m'), date('d'), date('Y')); //今天
  678. $td = $time - mktime(0, 0, 0, date('m'), date('d') + 1, date('Y')); //明天
  679. $timeDay = date('d', $time);
  680. $nowDay = date('d', time());
  681. if (0 == $d) {
  682. return '刚刚';
  683. }
  684. switch ($d) {
  685. case $d < $td :
  686. $fdate = '后天' . date('H:i', $time);
  687. break;
  688. case $d < 0 && $timeDay == $nowDay:
  689. $fdate = '今天' . date('H:i', $time);
  690. break;
  691. case $d < 0:
  692. $fdate = '明天' . date('H:i', $time);
  693. break;
  694. case $d < 60:
  695. $fdate = $d . '秒前';
  696. break;
  697. case $d < 3600:
  698. $fdate = floor($d / 60) . '分钟前';
  699. break;
  700. case $d < $dd :
  701. $fdate = floor($d / 3600) . '小时前';
  702. break;
  703. case $d < $yd :
  704. $fdate = '昨天' . date('H:i', $time);
  705. break;
  706. case $d < $byd :
  707. $fdate = '前天' . date('H:i', $time);
  708. break;
  709. case $d < $md :
  710. $fdate = date('m月d日 H:i', $time);
  711. break;
  712. case $d < $ld :
  713. $fdate = date('m月d日', $time);
  714. break;
  715. default :
  716. $fdate = date('Y年m月d日', $time);
  717. break;
  718. }
  719. return $fdate;
  720. }
  721. /**
  722. * @notes 生成随机数字
  723. * @param $table
  724. * @param string $field
  725. * @param int $length
  726. * @param string $prefix
  727. * @return string
  728. * @author 段誉
  729. * @date 2022/11/1 15:51
  730. */
  731. function create_rand_number($table, $field = 'sn', $length = 8, $prefix = '')
  732. {
  733. $rand_str = '';
  734. for ($i = 0; $i < $length; $i++) {
  735. $rand_str .= mt_rand(0, 9);
  736. }
  737. $sn = $prefix . $rand_str;
  738. if (Db::name($table)->where($field, $sn)->find()) {
  739. return create_rand_number($table, $field, $length, $prefix);
  740. }
  741. return $sn;
  742. }
  743. /**
  744. * @notes 文本超出隐藏
  745. * @param $string
  746. * @param $length
  747. * @return mixed|string
  748. * @author 段誉
  749. * @date 2022/10/31 14:14
  750. */
  751. function text_out_hidden($string, $length)
  752. {
  753. if (mb_strlen($string) > $length) {
  754. $string = mb_substr($string, 0, $length) . '..';
  755. }
  756. return $string;
  757. }
  758. /**
  759. * @notes Html中的图片绝对路径转为相对路径
  760. * @param $content
  761. * @return array|string|string[]
  762. * @author ljj
  763. * @date 2022/3/28 3:27 下午
  764. */
  765. function HtmlSetImage($content)
  766. {
  767. $domain = UrlServer::getFileUrl('/');
  768. preg_match_all("/<\s*img\s+[^>]*?src\s*=\s*(\'|\")(.*?)\\1[^>]*?\/?\s*>/i",$content,$matches);
  769. if(!empty($matches)){
  770. $imgurl = $matches[2];
  771. foreach($imgurl as $val){
  772. $setVal = str_replace($domain, '', $val);
  773. $content = str_replace($val,$setVal,$content);
  774. }
  775. }
  776. return $content;
  777. }
  778. /**
  779. * @notes Html中的图片相对路径转为绝对路径
  780. * @param $content
  781. * @author ljj
  782. * @date 2022/3/28 3:35 下午
  783. */
  784. function HtmlGetImage($content)
  785. {
  786. $domain = UrlServer::getFileUrl('/');
  787. preg_match_all("/<\s*img\s+[^>]*?src\s*=\s*(\'|\")(.*?)\\1[^>]*?\/?\s*>/i",$content,$matches);
  788. if(!empty($matches)){
  789. $imgurl = $matches[2];
  790. foreach($imgurl as $val){
  791. if (strstr($val, 'http://')) continue;
  792. if (strstr($val, 'https://')) continue;
  793. $content = str_replace($val,$domain.$val,$content);
  794. }
  795. }
  796. return $content;
  797. }
  798. function check_is_image($image) : bool
  799. {
  800. try {
  801. if (function_exists('exif_imagetype')) {
  802. $ImageType = exif_imagetype($image);
  803. } else {
  804. $info = getimagesize($image);
  805. $ImageType = $info ? $info[2] : false;
  806. }
  807. } catch (\Exception $e) {
  808. return false;
  809. }
  810. return in_array($ImageType, [1, 2, 3, 6]);
  811. }
  812. function check_is_video($video) : bool
  813. {
  814. $type = mime_content_type($video);
  815. return strpos($type, 'video') !== false;
  816. }
  817. //处理昵称
  818. function replaceNickname($nickname)
  819. {
  820. //过滤emoji 特殊符号
  821. $str = preg_replace_callback( '/./u',
  822. function (array $match) {
  823. if (Validate::isChs($match[0])) {
  824. return $match[0];
  825. }
  826. return strlen($match[0]) >= 4 ? '' : (ctype_graph($match[0]) ? $match[0] : '');
  827. },
  828. $nickname);
  829. return str_replace(' ', '', trim($str));
  830. }