helpers.php 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633
  1. <?php
  2. if (!function_exists('config_path')) {
  3. /**
  4. * Get the configuration path.
  5. *
  6. * @param string $path
  7. * @return string
  8. */
  9. function config_path($path = '')
  10. {
  11. return app()->basePath() . '/config' . ($path ? '/' . $path : $path);
  12. }
  13. }
  14. /**
  15. * 强转UTF-8
  16. * @param $str
  17. * @return mixed|string
  18. */
  19. function mbEncodingUtf8($str)
  20. {
  21. if (isUTF8($str))
  22. return $str;
  23. else {
  24. return mb_convert_encoding($str, 'UTF-8', 'ascii,GB2312,UTF-8,gbk');
  25. }
  26. }
  27. /**
  28. * http请求
  29. * @param $method
  30. * @param $url
  31. * @param array $params
  32. * @param array $headers
  33. * @param int $timeout
  34. * @param int $error 是否处理错误
  35. * @return string
  36. * @throws \App\Base\Exceptions\ApiException
  37. */
  38. function httpClient($method, $url, $params = [], $headers = [], $timeout = 0, $error = 1)
  39. {
  40. $curl = new \Curl\Curl();
  41. $curl->setOpt(CURLOPT_FOLLOWLOCATION, 5);
  42. $curl->setOpt(CURLOPT_ENCODING, "gzip");
  43. $curl->setUserAgent('Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36');
  44. //https 不验证ssl证书
  45. $curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
  46. if ($timeout > 0) {
  47. $curl->setOpt(CURLOPT_CONNECTTIMEOUT, 60);
  48. $curl->setOpt(CURLOPT_TIMEOUT, $timeout);
  49. }
  50. if (is_array($headers) && !empty($headers)) {
  51. foreach ($headers as $key => $value) {
  52. $curl->setHeader($key, $value);
  53. }
  54. }
  55. $method = strtolower($method);
  56. $curl->$method($url, $params);
  57. $code = $curl->http_status_code;
  58. $curl->close();
  59. if ($error && $code != 200) {
  60. \Illuminate\Support\Facades\Log::alert('code:' . $curl->error_code . ', error: ' . $curl->error, ['method' => $method, 'url' => $url, 'params' => $params]);
  61. throw new \App\Base\Exceptions\ApiException($curl->error_code);
  62. }
  63. return $curl->response;
  64. }
  65. /**
  66. * 对象重组
  67. * @param array $map
  68. * @param $key
  69. * @return array
  70. */
  71. function mapByKey(array $map, $key)
  72. {
  73. $data = [];
  74. foreach ($map as $item) {
  75. $data[$item[$key]] = $item;
  76. }
  77. return $data;
  78. }
  79. /**
  80. * 当前时间
  81. * @param bool|int $ts
  82. * @return string
  83. */
  84. function nowTime($ts = false)
  85. {
  86. return $ts ? date('Y-m-d H:i:s', $ts) : date('Y-m-d H:i:s');
  87. }
  88. /*
  89. * 日期间隔天数
  90. * */
  91. function dayDiff($date1, $date2)
  92. {
  93. $datetime1 = new \DateTime($date1);
  94. $datetime2 = new \DateTime($date2);
  95. $interval = $datetime1->diff($datetime2);
  96. return $interval->format('%R%a');
  97. }
  98. /**
  99. * 验证email格式
  100. * @param $email
  101. * @return bool
  102. */
  103. function validEmail($email)
  104. {
  105. $email = trim($email);
  106. return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
  107. $pattern = "/^((\w[-\w.+]*[-\w])|[-\w])@([A-Za-z0-9][-_A-Za-z0-9]*\.)+[A-Za-z]{2,20}$/";
  108. if (preg_match($pattern, $email)) {
  109. return true;
  110. }
  111. return false;
  112. }
  113. /**
  114. * 加密解密函数
  115. * @param $string
  116. * @param string $operation
  117. * @param string $key
  118. * @param int $expiry
  119. * @return bool|string
  120. */
  121. function authCode($string, $operation = 'DECODE', $key = '', $expiry = 0)
  122. {
  123. $ckey_length = 4;
  124. $key = md5($key ? $key : 'matchexpo');
  125. $keya = md5(substr($key, 0, 16));
  126. $keyb = md5(substr($key, 16, 16));
  127. $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';
  128. $cryptkey = $keya . md5($keya . $keyc);
  129. $key_length = strlen($cryptkey);
  130. $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
  131. $string_length = strlen($string);
  132. $result = '';
  133. $box = range(0, 255);
  134. $rndkey = array();
  135. for ($i = 0; $i <= 255; $i++) {
  136. $rndkey[$i] = ord($cryptkey[$i % $key_length]);
  137. }
  138. for ($j = $i = 0; $i < 256; $i++) {
  139. $j = ($j + $box[$i] + $rndkey[$i]) % 256;
  140. $tmp = $box[$i];
  141. $box[$i] = $box[$j];
  142. $box[$j] = $tmp;
  143. }
  144. for ($a = $j = $i = 0; $i < $string_length; $i++) {
  145. $a = ($a + 1) % 256;
  146. $j = ($j + $box[$a]) % 256;
  147. $tmp = $box[$a];
  148. $box[$a] = $box[$j];
  149. $box[$j] = $tmp;
  150. $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
  151. }
  152. if ($operation == 'DECODE') {
  153. if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
  154. return substr($result, 26);
  155. } else {
  156. return '';
  157. }
  158. } else {
  159. return $keyc . str_replace('=', '', base64_encode($result));
  160. }
  161. }
  162. /**
  163. * html转为text
  164. * @param $str
  165. * @param int $formatText
  166. * @return mixed
  167. */
  168. function html2text($str, $formatText = 1)
  169. {
  170. $str = preg_replace("/<style .*?<\\/style>/is", "", $str);
  171. $str = preg_replace("/<script .*?<\\/script>/is", "", $str);
  172. $str = preg_replace("/<br \\s*\\/>/i", $formatText ? ">>>>" : "", $str);
  173. $str = preg_replace("/<\\/?p>/i", $formatText ? ">>>>" : "", $str);
  174. $str = preg_replace("/<\\/?td>/i", "", $str);
  175. $str = preg_replace("/<\\/?div>/i", $formatText ? ">>>>" : "", $str);
  176. $str = preg_replace("/<\\/?blockquote>/i", "", $str);
  177. $str = preg_replace("/<\\/?li>/i", $formatText ? ">>>>" : "", $str);
  178. $str = preg_replace("/ /i", " ", $str);
  179. $str = preg_replace("/ /i", " ", $str);
  180. $str = preg_replace("/&/i", "&", $str);
  181. $str = preg_replace("/&/i", "&", $str);
  182. $str = preg_replace("/</i", "<", $str);
  183. $str = preg_replace("/</i", "<", $str);
  184. $str = preg_replace("/“/i", '"', $str);
  185. $str = preg_replace("/&ldquo/i", '"', $str);
  186. $str = preg_replace("/‘/i", "'", $str);
  187. $str = preg_replace("/&lsquo/i", "'", $str);
  188. $str = preg_replace("/’/i", "'", $str);
  189. $str = preg_replace("/&rsquo/i", "'", $str);
  190. $str = preg_replace("/>/i", ">", $str);
  191. $str = preg_replace("/>/i", ">", $str);
  192. $str = preg_replace("/”/i", '"', $str);
  193. $str = preg_replace("/&rdquo/i", '"', $str);
  194. $str = strip_tags($str);
  195. $str = html_entity_decode($str, ENT_QUOTES, "utf-8");
  196. $str = preg_replace("/&#.*?;/i", "", $str);
  197. return $str;
  198. }
  199. /**
  200. * 去掉内容中的html代码
  201. */
  202. function strip($str)
  203. {
  204. $str = str_replace("<br>", "", $str);
  205. return strip_tags($str);
  206. }
  207. /**
  208. * 创建多级文件目录
  209. * @param $dir
  210. * @return bool
  211. */
  212. function mkDirs($dir)
  213. {
  214. if (!is_dir($dir)) {
  215. if (!mkdirs(dirname($dir))) {
  216. return false;
  217. }
  218. if (!mkdir($dir, 0777, true)) {
  219. return false;
  220. }
  221. }
  222. return true;
  223. }
  224. /**
  225. * 下载远程文件
  226. * @param $fileUrl
  227. * @param $saveTo
  228. * @param $fileContent
  229. */
  230. function downloadRemoteFile($fileUrl, $saveTo, &$fileContent)
  231. {
  232. $ch = curl_init();
  233. curl_setopt($ch, CURLOPT_POST, 0);
  234. curl_setopt($ch, CURLOPT_URL, $fileUrl);
  235. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
  236. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  237. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  238. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 2);
  239. curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11");
  240. $fileContent = curl_exec($ch);
  241. curl_close($ch);
  242. $downloaded_file = fopen($saveTo, 'w');
  243. fwrite($downloaded_file, $fileContent);
  244. fclose($downloaded_file);
  245. }
  246. /**
  247. * 获取html的meta标签
  248. * @param $link
  249. * @return mixed
  250. */
  251. function getMetaOfLink($link)
  252. {
  253. if (!stristr($link, 'http')) {
  254. $link = 'http://' . $link;
  255. }
  256. $content = httpClient('get', $link);
  257. if (!$content) {
  258. $content = file_get_contents($link);
  259. }
  260. $encode = mb_detect_encoding($content, ['ASCII', 'UTF-8', 'GB2312', 'GBK', 'BIG5']);
  261. $content = iconv($encode, 'utf-8', $content);
  262. $reg = "/<title>(.*?)<\/title>/s";
  263. preg_match($reg, $content, $arr);
  264. if ($arr[1]) $meta['title'] = $arr[1];
  265. preg_match_all("/<meta[^>]+name=\"([^\"]*)\"[^>]" . "+content=\"([^\"]*)\"[^>]*>/i", $content, $r, PREG_PATTERN_ORDER);
  266. for ($i = 0; $i < count($r[1]); $i++) {
  267. if (strtolower($r[1][$i]) == "keywords") $meta['keywords'] = $r[2][$i];
  268. if (strtolower($r[1][$i]) == "description") $meta['description'] = $r[2][$i];
  269. }
  270. return $meta;
  271. }
  272. /**
  273. * 是否为utf8编码
  274. * @param $str
  275. * @return bool
  276. */
  277. function isUTF8($str)
  278. {
  279. $encoding = mb_detect_encoding($str, 'GB2312,UTF-8');
  280. if ($encoding == 'UTF-8') {
  281. return true;
  282. } else {
  283. return false;
  284. }
  285. }
  286. //格式化url
  287. function completeUrl($url)
  288. {
  289. if ($url) {
  290. $url = trim($url);
  291. if ($url[strlen($url) - 1] == '/') {
  292. $url = substr($url, 0, strlen($url) - 1);
  293. }
  294. }
  295. return $url;
  296. }
  297. //去掉http、https以及www
  298. function parseUrl($url)
  299. {
  300. if ($url) {
  301. $url = trim($url);
  302. $reg = '/^((https|http)?:\/\/)/';
  303. $strs = preg_split($reg, $url);
  304. $url = $strs[count($strs) - 1];
  305. if (strpos($url, 'www.') === 0)
  306. $url = substr($url, 4);
  307. }
  308. return $url;
  309. }
  310. /**
  311. * 从Request中获取客户端IP
  312. * @param \Illuminate\Http\Request $request
  313. * @return mixed|string|string[]|null
  314. */
  315. function getClientIpFromRequest(\Illuminate\Http\Request $request)
  316. {
  317. $remoteIp = $request->server->get('REMOTE_ADDR');
  318. $ip = '';
  319. if ($request->headers->has('X_FORWARDED_FOR')) {
  320. foreach (explode(',', $request->headers->get('X_FORWARDED_FOR')) as $v) {
  321. if ($v == 'unknown') {
  322. continue;
  323. }
  324. $clientValues[] = trim($v);
  325. }
  326. $ip = isset($clientValues[0]) ? $clientValues[0] : '';
  327. }
  328. if (!$ip && $request->server->has('HTTP_CLIENT_IP')) {
  329. $ip = $request->server->get('HTTP_CLIENT_IP');
  330. }
  331. if (!$ip && $request->headers->has('X-Real-IP')) {
  332. $ip = $request->headers->get('X-Real-IP');
  333. }
  334. $ip = $ip ? $ip : $remoteIp;
  335. // IP地址合法验证
  336. $long = sprintf("%u", ip2long($ip));
  337. $ip = $long ? $ip : ($remoteIp ?: '0.0.0.0');
  338. return $ip;
  339. }
  340. /**
  341. * 获取客户端IP地址
  342. * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
  343. * @param boolean $adv 是否进行高级模式获取(有可能被伪装)
  344. * @return mixed
  345. */
  346. function getClientIp($type = 0, $adv = false)
  347. {
  348. $type = $type ? 1 : 0;
  349. static $ip = NULL;
  350. if ($ip !== NULL) return $ip[$type];
  351. if ($adv) {
  352. if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  353. $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
  354. $pos = array_search('unknown', $arr);
  355. if (false !== $pos) unset($arr[$pos]);
  356. $ip = trim($arr[0]);
  357. } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
  358. $ip = $_SERVER['HTTP_CLIENT_IP'];
  359. } elseif (isset($_SERVER['REMOTE_ADDR'])) {
  360. $ip = $_SERVER['REMOTE_ADDR'];
  361. }
  362. } elseif (isset($_SERVER['REMOTE_ADDR'])) {
  363. $ip = $_SERVER['REMOTE_ADDR'];
  364. }
  365. // IP地址合法验证
  366. $long = sprintf("%u", ip2long($ip));
  367. $ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
  368. return $ip[$type];
  369. }
  370. /**
  371. * 其他时区时间转为北京时间 $timezone_time 时区时间,$timezone时区
  372. * @param $timezoneTime
  373. * @param $timezone
  374. * @param int $isDefault
  375. * @return false|string
  376. */
  377. function toTimezone($timezoneTime, $timezone, $isDefault = 0)
  378. {
  379. $beiJin = 8;
  380. if (!$isDefault) {
  381. $diffS = ($beiJin - $timezone) * 3600;//相差秒数
  382. } else {
  383. $diffS = ($timezone - $beiJin) * 3600;//相差秒数
  384. }
  385. $zoneTime = strtotime($timezoneTime);
  386. $time = date('Y-m-d H:i', $zoneTime + $diffS);
  387. return $time;
  388. }
  389. /**
  390. * 时间显示格式
  391. * @param $theTime
  392. * @param $isShort true-短格式
  393. * @return false|string
  394. */
  395. function timeTran($theTime, $isShort = false)
  396. {
  397. $nowTime = time();
  398. $showTime = $theTime;
  399. $dur = $nowTime - $showTime;
  400. //$monthLastTime = strtotime(date('Y-m-01', $theTime). ' 1 month -1 day'); //当月最后一天
  401. $transKeySuffix = '';
  402. if (!$isShort ) {
  403. $transKeySuffix = '_long';
  404. }
  405. if ($dur <= 60) {
  406. return transL("common.now", "刚刚");
  407. } elseif ($dur <= 3600) {
  408. $number = floor($dur / 60);
  409. return $number . ' '. transL("common.minute_ago".$transKeySuffix, "分钟前", ['s'=>($number ? 's' : '')]);
  410. } elseif ($dur <= 86400) {
  411. $number = floor($dur / 3600);
  412. return $number . ' '. transL("common.hour_ago".$transKeySuffix, "小时前", ['s'=>($number ? 's' : '')]);
  413. } elseif ($dur <= 86400 * 30) {
  414. $number = floor($dur / 86400);
  415. return $number . ' '. transL("common.day_ago" . $transKeySuffix, "天前", ['s'=>($number ? 's' : '')]);
  416. } elseif ($dur <= 86400 * 30 * 12) {
  417. $number = floor($dur / (86400 * 30));
  418. return $number . ' '. transL("common.month_ago".$transKeySuffix, "月前", ['s'=>($number ? 's' : '')]);
  419. } else {
  420. $number = floor($dur / (86400 * 30 * 12));
  421. return $number . ' '. transL("common.year_ago".$transKeySuffix, "年前", ['s'=>($number ? 's' : '')]);
  422. }
  423. }
  424. /**
  425. * 数字转化
  426. */
  427. function formatNumber($number) {
  428. $length = strlen($number); //数字长度
  429. $lang = app('translator')->getLocale();
  430. if ($lang == 'en-us') { //英文的单位不一样
  431. if ($length > 9) { //十亿单位
  432. $str = round($number / 1000000000, 1).transL("common.billion", "十亿");
  433. } elseif ($length > 6) { //百万单位
  434. $str = round($number / 1000000, 1).transL("common.million", "百万");
  435. } elseif ($length > 3) { //千单位
  436. $str = round($number / 1000, 1).transL("common.thousand", "千");
  437. } else {
  438. return $number;
  439. }
  440. } else {
  441. if ($length > 8) { //亿单位
  442. $str = round($number / 100000000, 1).transL("common.hundred_million", "亿");
  443. } elseif ($length > 4) { //万单位
  444. $str = round($number / 10000, 1).transL("common.ten_thousand", "万");
  445. } elseif ($length > 3) { //千单位
  446. $str = round($number / 1000, 1).transL("common.thousand", "千");
  447. } else {
  448. return $number;
  449. }
  450. }
  451. return $str;
  452. }
  453. /**
  454. * 格式化金额
  455. */
  456. function formatAmount($amount = "")
  457. {
  458. $lang = app('translator')->getLocale();
  459. if ($lang == 'en-us') {
  460. return '$' . $amount;
  461. } else {
  462. return '¥' . $amount;
  463. }
  464. }
  465. /**
  466. * 根据数组某个字段排序
  467. * @param $array 待排序数组
  468. * @param $field 排序字段
  469. * @param bool $desc 是否降序
  470. */
  471. function sortArrByField(&$array, $field, $desc = false)
  472. {
  473. $fieldArr = array();
  474. foreach ($array as $k => $v) {
  475. $fieldArr[$k] = strtolower($v[$field]);
  476. }
  477. $sort = $desc == false ? SORT_ASC : SORT_DESC;
  478. array_multisort($fieldArr, $sort, $array);
  479. }
  480. //将查询字符中的特殊查询字符处理掉
  481. function formatQueryKey($key)
  482. {
  483. $key = str_replace('\\', '\\\\\\\\', $key);
  484. $key = str_replace('%', '\\%', $key);
  485. $key = str_replace('_', '\\_', $key);
  486. $key = str_replace("'", "\\'", $key);
  487. $key = str_replace('"', '\\"', $key);
  488. if (strstr($key, '[!')) {
  489. $key = str_replace('[!', '\\[\\!', $key);
  490. } elseif (strstr($key, '[^')) {
  491. $key = str_replace('[!', '\\[\\^', $key);
  492. } elseif (strstr($key, '[')) {
  493. $key = str_replace('[!', '\\[', $key);
  494. }
  495. return $key;
  496. }
  497. //图片转base64
  498. function base64EncodeImage($image_file)
  499. {
  500. $base64_image = '';
  501. $image_data = fread(fopen($image_file, 'r'), filesize($image_file));
  502. $base64_image = chunk_split(base64_encode($image_data));
  503. return $base64_image;
  504. }
  505. /*
  506. * 把数组转换成树
  507. */
  508. function listToTree($list, $root = 0, $pk = 'id', $pid = 'pid', $child = '_child')
  509. {
  510. // 创建Tree
  511. $tree = array();
  512. if (is_array($list)) {
  513. // 创建基于主键的数组引用
  514. $refer = array();
  515. foreach ($list as $key => $data) {
  516. $refer[$data[$pk]] = &$list[$key];
  517. }
  518. foreach ($list as $key => $data) {
  519. // 判断是否存在parent
  520. $parentId = 0;
  521. if (isset($data[$pid])) {
  522. $parentId = $data[$pid];
  523. }
  524. if ((string)$root == $parentId) {
  525. $tree[] = &$list[$key];
  526. } else {
  527. if (isset($refer[$parentId])) {
  528. $parent = &$refer[$parentId];
  529. $parent[$child][] = &$list[$key];
  530. } else {
  531. //如果找不到父项那么自己就是父项
  532. $tree[] =& $list[$key];
  533. }
  534. }
  535. }
  536. }
  537. return $tree;
  538. }
  539. /**
  540. * 过滤并返回整形数组
  541. * @param array $arr
  542. */
  543. function filterIntArray($arr)
  544. {
  545. if ($arr) {
  546. foreach ($arr as $k => $v) {
  547. $arr[$k] = (int)$v;
  548. if (!$arr[$k]) {
  549. unset($arr[$k]);
  550. }
  551. }
  552. }
  553. return $arr;
  554. }
  555. //增加redis的连接判断,默认如果连接错误会抛出异常,这边捕获异常,下次会重新连接
  556. function checkRedisPing($config = null)
  557. {
  558. if ($config) {
  559. $redis = app('redis')->connection($config);
  560. } else {
  561. $redis = app('redis.connection');
  562. }
  563. try {
  564. $redis->ping();
  565. } catch (\Exception $e) {
  566. }
  567. }
  568. /**
  569. * 调试sql语句
  570. */
  571. function sqlDump()
  572. {
  573. \DB::listen(function ($query) {
  574. $i = 0;
  575. $rawSql = preg_replace_callback('/\?/', function ($matches) use ($query, &$i) {
  576. $item = isset($query->bindings[$i]) ? $query->bindings[$i] : $matches[0];
  577. $i++;
  578. return gettype($item) == 'string' ? "'$item'" : $item;
  579. }, $query->sql);
  580. // \Log::info($rawSql);
  581. echo $rawSql, "\n\n";
  582. });
  583. }
  584. function transL($id = null, $msg = '', $replace = [], $locale = null)
  585. {
  586. $data = trans($id, $replace, $locale);
  587. if (is_array($data)) {
  588. $data = $data[1];
  589. }
  590. if ($replace) {
  591. foreach ($replace as $key => $item) {
  592. $data = str_replace('{' . $key . '}', $item, $data);
  593. }
  594. }
  595. return $data ?: $msg;
  596. }
  597. /**
  598. * 获取分页数组
  599. * @param array $data
  600. * @param int $total
  601. * @param null $perPage
  602. * @param null $page
  603. * @param string $pageName
  604. * @return mixed
  605. */
  606. function getPaginateArray($data = [], $total = 0, $perPage = null, $page = null, $pageName = 'page')
  607. {
  608. $page = $page ?: \Illuminate\Pagination\Paginator::resolveCurrentPage($pageName);
  609. $perPage = $perPage === null ? config('app.app_rows', 15) : $perPage;
  610. return (new \Illuminate\Pagination\LengthAwarePaginator($data, $total, $perPage, $page, [
  611. 'path' => \Illuminate\Pagination\Paginator::resolveCurrentPath(),
  612. 'pageName' => 'page'
  613. ]))->toArray();
  614. }
  615. /**
  616. * 转换秒数为 3h39'25" 的格式
  617. * @param $seconds
  618. * @return string
  619. */
  620. function convertDuration($seconds)
  621. {
  622. if ($seconds > 0) {
  623. $str = '';
  624. $unit = ['"', '\'', 'h'];
  625. foreach ($unit as $i => $u) {
  626. $v = $seconds % 60;
  627. $seconds = floor($seconds / 60);
  628. if ($v > 0) {
  629. $str = $v . $u . $str;
  630. }
  631. if (!$seconds) {
  632. break;
  633. }
  634. }
  635. return $str;
  636. }
  637. return '0"';
  638. }
  639. //转换大小
  640. function conversionByte($size)
  641. {
  642. $kb = 1024; // 1KB(Kibibyte,千字节)=1024B,
  643. $mb = 1024 * $kb; //1MB(Mebibyte,兆字节,简称“兆”)=1024KB,
  644. $gb = 1024 * $mb; // 1GB(Gigabyte,吉字节,又称“千兆”)=1024MB,
  645. $tb = 1024 * $gb; // 1TB(Terabyte,万亿字节,太字节)=1024GB,
  646. $pb = 1024 * $tb; //1PB(Petabyte,千万亿字节,拍字节)=1024TB,
  647. $fb = 1024 * $pb; //1EB(Exabyte,百亿亿字节,艾字节)=1024PB,
  648. $zb = 1024 * $fb; //1ZB(Zettabyte,十万亿亿字节,泽字节)= 1024EB,
  649. $yb = 1024 * $zb; //1YB(Yottabyte,一亿亿亿字节,尧字节)= 1024ZB,
  650. $bb = 1024 * $yb; //1BB(Brontobyte,一千亿亿亿字节)= 1024YB
  651. if ($size < $kb) {
  652. return $size . " B";
  653. } else if ($size < $mb) {
  654. return round($size / $kb, 2) . " KB";
  655. } else if ($size < $gb) {
  656. return round($size / $mb, 2) . " MB";
  657. } else if ($size < $tb) {
  658. return round($size / $gb, 2) . " GB";
  659. } else if ($size < $pb) {
  660. return round($size / $tb, 2) . " TB";
  661. } else if ($size < $fb) {
  662. return round($size / $pb, 2) . " PB";
  663. } else if ($size < $zb) {
  664. return round($size / $fb, 2) . " EB";
  665. } else if ($size < $yb) {
  666. return round($size / $zb, 2) . " ZB";
  667. } else {
  668. return round($size / $bb, 2) . " YB";
  669. }
  670. }
  671. //隐藏手机号
  672. function hidePhone($phone)
  673. {
  674. return substr_replace($phone, '****', 3, 4);
  675. }
  676. //隐藏字符串
  677. function hideString($str){
  678. $len= mb_strlen($str);
  679. $retStr='';
  680. if($len>0){
  681. if($len>7){
  682. $retStr=mb_substr($str,0,3).'****'.mb_substr($str,-3);
  683. }else if($len>3){
  684. $retStr=mb_substr($str,0,1).'****'.mb_substr($str,-1);
  685. }else{
  686. $retStr='****'.mb_substr($str,-1);
  687. }
  688. }
  689. return $retStr;
  690. }
  691. function emailMatch($email)
  692. {
  693. return validEmail($email);
  694. }
  695. function changeCharset($content, $fromCharset, $toCharset)
  696. {
  697. if (empty($fromCharset)) {
  698. $content = mb_convert_encoding($content, $toCharset, 'ascii,UTF-8,GB18030');
  699. } else {
  700. if ($fromCharset != $toCharset) {
  701. $content = iconv($fromCharset, $toCharset, $content);
  702. }
  703. }
  704. return $content;
  705. }
  706. /*
  707. * 调用Http Get,或Post方法
  708. */
  709. function getHttpContent($url, $data = null, $timeout = 20, $headers = '', $method = null)
  710. {
  711. $ch = curl_init();
  712. // $timeout = 5;
  713. curl_setopt($ch, CURLOPT_URL, $url);
  714. curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
  715. if ($data) {
  716. curl_setopt($ch, CURLOPT_POST, 1);
  717. curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  718. }
  719. // curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
  720. if (stristr($url, 'https')) {
  721. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  722. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
  723. // curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
  724. }
  725. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 2);
  726. curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
  727. curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
  728. curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
  729. if ($method) {
  730. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
  731. }
  732. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  733. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
  734. curl_setopt($ch, CURLOPT_HEADER, 0);
  735. if (!empty($headers)) {
  736. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  737. }
  738. $content = curl_exec($ch);
  739. $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  740. if ($httpCode == 404) {
  741. $content = null;
  742. }
  743. // print_r(curl_error($ch));
  744. curl_close($ch);
  745. return $content;
  746. }
  747. function treeToOptionArr(&$tree, $level = 0, $name = 'title', $child = 'sub', $prefix = ' ')
  748. {
  749. $optionArr = [];
  750. if (is_array($tree)) {
  751. foreach ($tree as $t) {
  752. $p = $t;
  753. $p[$name] = str_repeat($prefix, $level) . $t[$name];
  754. if (isset($t[$child])) {
  755. unset($p[$child]);
  756. $optionArr[] = $p;
  757. $optionArr = array_merge($optionArr, treeToOptionArr($t[$child], $level + 1, $name, $child, $prefix));
  758. } else {
  759. $optionArr[] = $p;
  760. }
  761. }
  762. }
  763. return $optionArr;
  764. }
  765. function getOs()
  766. {
  767. if (!empty($_SERVER['HTTP_USER_AGENT'])) {
  768. $OS = $_SERVER['HTTP_USER_AGENT'];
  769. if (preg_match('/win/i', $OS)) {
  770. $OS = 'Windows';
  771. } elseif (preg_match('/mac/i', $OS)) {
  772. $OS = 'MAC';
  773. } elseif (preg_match('/linux/i', $OS)) {
  774. $OS = 'Linux';
  775. } elseif (preg_match('/unix/i', $OS)) {
  776. $OS = 'Unix';
  777. } elseif (preg_match('/bsd/i', $OS)) {
  778. $OS = 'BSD';
  779. } else {
  780. $OS = 'Other';
  781. }
  782. return $OS;
  783. } else {
  784. return "unknow";
  785. }
  786. }
  787. //计算时区
  788. function calcTimezone($time = null, $timezone = 8, $isDefault = 0)
  789. {
  790. if (!$time) {
  791. return '';
  792. }
  793. $default = 8;
  794. $minute = 0;
  795. $diff = $default - $timezone;
  796. if ($isDefault) {
  797. $pre = '+';
  798. } else {
  799. $pre = '-';
  800. }
  801. if ($timezone < 8) {
  802. $diff = $default - $timezone;
  803. if ($isDefault) {
  804. $pre = '-';
  805. } else {
  806. $pre = '+';
  807. }
  808. } else {
  809. $diff = $timezone - $default;
  810. }
  811. // echo $diff.'='.$pre;exit;
  812. if (ceil($diff) != $diff) {
  813. $tmp = explode(".", floatval($diff) . "");
  814. $minute = 60 * floatval("0." . $tmp[1]);
  815. $diff = intval($diff);
  816. }
  817. $time = strtotime($pre . $diff . ' hours', strtotime($time));
  818. if ($minute) {
  819. $time = strtotime($pre . $minute . ' minutes', $time);
  820. }
  821. return date('Y-m-d H:i', $time);
  822. }
  823. /**
  824. * 将字符串插入到另一个字符串的指定位置
  825. * @param $str 原字符串
  826. * @param $i 位置
  827. * @param $substr 插入的字符串
  828. * @return string
  829. */
  830. function strInsert($str, $i, $substr)
  831. {
  832. $startstr = '';
  833. $laststr = '';
  834. for ($j = 0; $j < $i; $j++) {
  835. $startstr .= $str[$j];
  836. }
  837. for ($j = $i; $j < strlen($str); $j++) {
  838. $laststr .= $str[$j];
  839. }
  840. $str = ($startstr . $substr . $laststr);
  841. return $str;
  842. }
  843. // 生成GUID
  844. function createGuid()
  845. {
  846. $charid = strtoupper(md5(uniqid(mt_rand(), true)));
  847. $hyphen = chr(45);// "-"
  848. $uuid = chr(123)// "{"
  849. . substr($charid, 0, 8) . $hyphen
  850. . substr($charid, 8, 4) . $hyphen
  851. . substr($charid, 12, 4) . $hyphen
  852. . substr($charid, 16, 4) . $hyphen
  853. . substr($charid, 20, 12)
  854. . chr(125);// "}"
  855. return $uuid;
  856. }
  857. function getEmailName($email)
  858. {
  859. $tmp = explode("@", $email);
  860. return $tmp[0];
  861. }
  862. if (!function_exists('ftok')) {
  863. function ftok($filePath, $projectId)
  864. {
  865. $fileStats = stat($filePath);
  866. if (!$fileStats) {
  867. return -1;
  868. }
  869. return sprintf('%u',
  870. ($fileStats['ino'] & 0xffff) | (($fileStats['dev'] & 0xff) << 16) | ((ord($projectId) & 0xff) << 24)
  871. );
  872. }
  873. }
  874. function unicode2utf8($str)
  875. {
  876. if (!$str) return $str;
  877. $decode = json_decode($str);
  878. if ($decode) return $decode;
  879. $str = '["' . $str . '"]';
  880. $decode = json_decode($str);
  881. if (count($decode) == 1) {
  882. return $decode[0];
  883. }
  884. return $str;
  885. }
  886. /**
  887. * 电话过滤 空格、+、- 字符
  888. * @param $phone
  889. * @return null|string|string[]
  890. */
  891. function filterPhone($phone)
  892. {
  893. return "'" . preg_replace('/(\s+)|(\-+)|(\++)/', '', $phone) . "'";
  894. }
  895. /*
  896. * 邮箱过滤 “.”“,”“ ”(空格)“-”
  897. * @param $email
  898. * @return null|string|string[]
  899. * */
  900. function filterEmail($email)
  901. {
  902. $email = trim($email);
  903. $email = trim($email, ".");
  904. $email = trim($email, ";");
  905. $email = trim($email, "-");
  906. $email = trim($email, ",");
  907. return $email;
  908. }
  909. /**
  910. * url解析
  911. * @param $input
  912. * @return bool|string
  913. */
  914. function base64_url_decode($input)
  915. {
  916. return base64_decode(strtr($input, '-_', '+/'));
  917. }
  918. /*
  919. * 判断手机号是否合法
  920. * */
  921. function validPhone($phone)
  922. {
  923. $phone = trim($phone);
  924. $pattern = "/^1[345789]\d{9}$/";
  925. if (preg_match($pattern, $phone)) {
  926. return true;
  927. } else {
  928. return false;
  929. }
  930. }
  931. /**
  932. * 输出导出excel文件到浏览器
  933. * @param $formatData
  934. * @param $fileName
  935. * @param $header
  936. * @param null $expire
  937. */
  938. function outputExcelDumpFile(&$formatData, $fileName, $header, $expire = null, $setTimeLimit = 600)
  939. {
  940. $response = new \Symfony\Component\HttpFoundation\StreamedResponse(function () use (&$formatData, &$header, $setTimeLimit) {
  941. set_time_limit($setTimeLimit);
  942. $phpExcel = new \PHPExcel();
  943. $phpExcel->getProperties()->setCreator("matchexpo");
  944. $phpExcel->setActiveSheetIndex(0);
  945. $phpExcel->getActiveSheet()->setTitle('Sheet1');
  946. $startCell = 'A1';
  947. if (!empty($header)) {
  948. $phpExcel->getActiveSheet()->fromArray($header, null, $startCell);
  949. $startCell = 'A2';
  950. }
  951. $phpExcel->getActiveSheet()->fromArray($formatData, null, $startCell);
  952. $objWriter = \PHPExcel_IOFactory::createWriter($phpExcel, 'Excel5');
  953. $objWriter->save("php://output");
  954. ini_restore('max_execution_time');
  955. });
  956. return setDumpFileHead($response, $fileName, null, 'application/vnd.ms-excel');
  957. }
  958. /**
  959. * 设置导出文件header
  960. * @param $response
  961. * @param $fileName
  962. * @param integer $expire
  963. * @param string $contentType
  964. * @return mixed
  965. */
  966. function setDumpFileHead($response, $fileName, $expire = null, $contentType = null)
  967. {
  968. if (!$expire) {
  969. $expire = 180;
  970. }
  971. if (!$contentType) {
  972. $contentType = 'application/octet-stream';
  973. }
  974. if ((string)$fileName !== '') {
  975. $response->headers->set('Pragma', 'public');
  976. $response->headers->set('Cache-Control', 'max-age=' . $expire);
  977. $response->headers->set('Cache-Control', 'post-check=0, pre-check=0', false);
  978. $response->headers->set('Expires', gmdate("D, d M Y H:i:s", time() + $expire) . "GMT");
  979. $response->headers->set('Last-Modified', gmdate("D, d M Y H:i:s", time()) . "GMT");
  980. $response->headers->set('Content-Disposition', 'attachment; filename="' . rawurlencode($fileName) . '"; filename*=utf-8\'\'' . rawurlencode($fileName));
  981. $response->headers->set('X-Accel-Buffering', 'no');
  982. }
  983. $response->headers->set('Content-type', $contentType);
  984. return $response;
  985. }
  986. /**
  987. * 输出导出csv文件到浏览器
  988. * @param $formatData 数据数组
  989. * @param $fileName 导出文件名
  990. * @param callable $rowHandler 处理数据的回调函数,接收两个参数:数据数组和文件句柄(&$formatData, $fp)
  991. * @param $header 表头数组
  992. * @param null $expire 过期秒数
  993. * @return mixed
  994. * @throws \Exception
  995. */
  996. function outputCsvDumpFile(&$formatData, $fileName, callable $rowHandler, $header, $expire = null, $setTimeLimit = 600)
  997. {
  998. //节省内存
  999. $response = new \Symfony\Component\HttpFoundation\StreamedResponse(function () use (&$formatData, $rowHandler, &$header, $setTimeLimit) {
  1000. try {
  1001. set_time_limit($setTimeLimit);
  1002. $fp = fopen('php://output', 'w');
  1003. //add BOM to fix UTF-8 in Excel
  1004. fputs($fp, $bom = (chr(0xEF) . chr(0xBB) . chr(0xBF)));
  1005. //写表头
  1006. if ($header) {
  1007. fputcsv($fp, $header);
  1008. }
  1009. //写内容
  1010. $rowHandler($formatData, $fp);
  1011. fclose($fp);
  1012. ini_restore('max_execution_time');
  1013. } catch (\Exception $e) {
  1014. ini_restore('max_execution_time');
  1015. if (isset($fp) && is_resource($fp)) {
  1016. @fclose($fp);
  1017. }
  1018. throw $e;
  1019. }
  1020. });
  1021. return setDumpFileHead($response, $fileName, $expire);
  1022. }
  1023. /**
  1024. * 通过callback导出文件
  1025. * @param callable $callback
  1026. * @param $fileName
  1027. * @param null $expire
  1028. * @return mixed
  1029. */
  1030. function outputDumpFileDynamic(callable $callback, $fileName, $expire = null, $contentType = null)
  1031. {
  1032. $response = new \Symfony\Component\HttpFoundation\StreamedResponse($callback);
  1033. return setDumpFileHead($response, $fileName, $expire, $contentType);
  1034. }
  1035. /**
  1036. * 根据数组字段检验数组唯一性
  1037. * @param $keys 检验数组键值
  1038. * @param $arrs 检验数组
  1039. * @param $flitNull 是否检验空值
  1040. * @return array
  1041. */
  1042. function checkArrayUnique($keys, $arrs, $flitNull = true)
  1043. {
  1044. $unique_arr = array();
  1045. $repeat_arr = array();
  1046. foreach ($keys as $key) {
  1047. foreach ($arrs as $k => $v) {
  1048. if (!isset($v[$key]) && $flitNull) break;
  1049. $str = "";
  1050. foreach ([$key] as $a => $b) {
  1051. $str .= "{$v[$b]},";
  1052. }
  1053. if (!in_array($str, $unique_arr)) {
  1054. $unique_arr[] = $str;
  1055. } else {
  1056. if ($flitNull) $repeat_arr[$key] = $v;
  1057. if (!$flitNull && !empty($v[$b])) $repeat_arr[$key] = $v;
  1058. }
  1059. }
  1060. }
  1061. return $repeat_arr;
  1062. }
  1063. /**
  1064. * 过滤掉emoji表情
  1065. * @param $str
  1066. * @return null|string|string[]
  1067. */
  1068. function stripEmoji($str)
  1069. {
  1070. $str = preg_replace_callback(
  1071. '/./u',
  1072. function (array $match) {
  1073. return strlen($match[0]) >= 4 ? '' : $match[0];
  1074. },
  1075. $str);
  1076. return $str;
  1077. }
  1078. /**
  1079. * 过滤4字节以上的utf8字符
  1080. * @param $string
  1081. * @return string|string[]|null
  1082. */
  1083. function removeUtf8Mb4Char($string)
  1084. {
  1085. $regx = '/[^\x{00}-\x{7F}\x{80}-\x{07FF}\x{0800}-\x{D7FF}\x{E000}-\x{FFFF}]/u';
  1086. $result = preg_replace($regx, '', $string);
  1087. if ($result !== null) {
  1088. $string = $result;
  1089. }
  1090. return $string;
  1091. }
  1092. /**
  1093. * 格式化秒为时分秒
  1094. * @param $seconds
  1095. * @return string
  1096. */
  1097. function formatSeconds($seconds)
  1098. {
  1099. $h = floor($seconds / 3600);
  1100. $str = gmstrftime("%M'%S\"", $seconds);
  1101. if ($h > 0) {
  1102. return $h . 'h' . $str;
  1103. }
  1104. return $str;
  1105. }
  1106. /**
  1107. * 过滤Emoji表情
  1108. * @param $str
  1109. * @return string|string[]|null
  1110. */
  1111. function filterEmoji($str)
  1112. {
  1113. $out = preg_replace_callback(
  1114. '/./u', function (array $match) {
  1115. return strlen($match[0]) >= 4 ? '' : $match[0];
  1116. }, $str);
  1117. return $out;
  1118. }
  1119. function getRequestId()
  1120. {
  1121. $ip = request()->header('request_id');
  1122. $ip = !empty($ip) ? (is_array($ip) ? current($ip) : $ip) : '';
  1123. return $ip;
  1124. }
  1125. if (!function_exists('starts_with')) {
  1126. /**
  1127. * Determine if a given string starts with a given substring.
  1128. *
  1129. * @param string $haystack
  1130. * @param string|array $needles
  1131. * @return bool
  1132. */
  1133. function starts_with($haystack, $needles)
  1134. {
  1135. return \Illuminate\Support\Str::startsWith($haystack, $needles);
  1136. }
  1137. }
  1138. if (!function_exists('snake_case')) {
  1139. function snake_case($value, $delimiter = '_')
  1140. {
  1141. return \Illuminate\Support\Str::snake($value, $delimiter);
  1142. }
  1143. }
  1144. /**
  1145. * 对图片前面的网址进行处理
  1146. * @param $img
  1147. * @param string $root
  1148. * @return string
  1149. */
  1150. function checkRootImg($img, $root = '')
  1151. {
  1152. $root = $root ?: config('app.attachment_host');
  1153. if ($img && !stristr($img, $root)) {
  1154. $img = $root . $img;
  1155. }
  1156. return $img;
  1157. }
  1158. /**
  1159. * 处理转化密码加密
  1160. * @param $password
  1161. * @return string
  1162. */
  1163. function converPassword($password)
  1164. {
  1165. return md5($password);
  1166. }
  1167. /**
  1168. * 生成随机数
  1169. */
  1170. function random($length, $numeric = 0)
  1171. {
  1172. mt_srand((double)microtime() * 1000000);
  1173. if ($numeric) {
  1174. $hash = sprintf('%0' . $length . 'd', mt_rand(0, pow(10, $length) - 1));
  1175. } else {
  1176. $hash = '';
  1177. $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
  1178. $max = strlen($chars) - 1;
  1179. for ($i = 0; $i < $length; $i++) {
  1180. $hash .= $chars[mt_rand(0, $max)];
  1181. }
  1182. }
  1183. return $hash;
  1184. }
  1185. /**
  1186. * 获取随机字符串
  1187. * @param $prefix
  1188. * @return string
  1189. */
  1190. function getRandomStr($prefix = 'WX')
  1191. {
  1192. $addHead = '';
  1193. $addTail = '';
  1194. $i = 0;
  1195. while ($i < 3) {
  1196. $addHead .= mt_rand(0, 9);
  1197. $addTail .= mt_rand(0, 9);
  1198. $i = $i + 1;
  1199. }
  1200. return $prefix . $addHead . time() . $addTail;
  1201. }
  1202. /**
  1203. * 构造返回页面数据
  1204. * @param $data //数据
  1205. * @param $formNb //开始数量
  1206. * @param $page //页数
  1207. * @param $perPageSize //每页数量
  1208. * @param $total //总数量
  1209. * @return mixed
  1210. */
  1211. function buildPage($data = [], $formNb = 0, $page = 1, $perPageSize = 10, $total = 0)
  1212. {
  1213. $lastPage = ceil($total / $perPageSize);
  1214. $toNb = $page * $perPageSize;
  1215. if (empty($formNb)) {
  1216. $formNb = $toNb - $perPageSize;
  1217. }
  1218. if ($toNb > $total) {
  1219. $toNb = $total;
  1220. }
  1221. $resultDdata = array(
  1222. 'current_page' => $page,
  1223. 'data' => $data,
  1224. 'from' => $formNb,
  1225. 'last_page' => $lastPage,
  1226. 'per_page' => $perPageSize,
  1227. 'to' => $toNb,
  1228. 'total' => $total,
  1229. );
  1230. return $resultDdata;
  1231. }
  1232. /**
  1233. * 获取岁数
  1234. * @param DateTime $date 日期
  1235. * @param integer $type 类型 1虚岁 2周岁
  1236. * */
  1237. function getAgeByBirth($date, $type = 1)
  1238. {
  1239. $nowYear = date("Y", time());
  1240. $nowMonth = date("m", time());
  1241. $nowDay = date("d", time());
  1242. $birthYear = date("Y", $date);
  1243. $birthMonth = date("m", $date);
  1244. $birthDay = date("d", $date);
  1245. if ($type == 1) {
  1246. $age = $nowYear - ($birthYear - 1);
  1247. } else {
  1248. if ($nowMonth < $birthMonth) {
  1249. $age = $nowYear - $birthYear - 1;
  1250. } elseif ($nowMonth == $birthMonth) {
  1251. if ($nowDay < $birthDay) {
  1252. $age = $nowYear - $birthYear - 1;
  1253. } else {
  1254. $age = $nowYear - $birthYear;
  1255. }
  1256. } else {
  1257. $age = $nowYear - $birthYear;
  1258. }
  1259. }
  1260. return $age;
  1261. }
  1262. if (!function_exists('config_path')) {
  1263. /* Get the configuration path. @param string $path @return string */
  1264. function config_path($path = '')
  1265. {
  1266. return app()->basePath() . '/config' . ($path ? '/' . $path : $path);
  1267. }
  1268. }
  1269. /**
  1270. * 按key对二维数组去重
  1271. */
  1272. if (!function_exists('assoc_unique')) {
  1273. function assoc_unique($arr, $key)
  1274. {
  1275. $tmp_arr = array();
  1276. foreach ($arr as $k => $v) {
  1277. if (in_array($v[$key], $tmp_arr)) {//搜索$v[$key]是否在$tmp_arr数组中存在,若存在返回true
  1278. unset($arr[$k]);
  1279. } else {
  1280. $tmp_arr[] = $v[$key];
  1281. }
  1282. }
  1283. sort($arr); //sort函数对数组进行排序
  1284. return $arr;
  1285. }
  1286. }
  1287. /**
  1288. * 内部的一维数组不能完全相同,而删除重复项
  1289. */
  1290. if (!function_exists('array_unique_fb')) {
  1291. function array_unique_fb($array)
  1292. {
  1293. $serializeArrs = array_map('serialize', $array);
  1294. $uniqueArrs = array_unique($serializeArrs);
  1295. $unserializeArrs = array_map('unserialize', $uniqueArrs);
  1296. return $unserializeArrs;
  1297. }
  1298. }
  1299. /**
  1300. * 汉语 - 给用户自动生成昵称
  1301. * @param int $type 1生成昵称,2生成姓名
  1302. * @return mixed|string
  1303. */
  1304. if (!function_exists('randNickName')) {
  1305. function randNickName($type = 1)
  1306. {
  1307. /**
  1308. * 随机昵称 形容词
  1309. */
  1310. $nick_name_tou = ['迷你的', '鲜艳的', '飞快的', '真实的', '清新的', '幸福的', '可耐的', '快乐的', '冷静的', '醉熏的', '潇洒的', '糊涂的', '积极的', '冷酷的', '深情的', '粗暴的',
  1311. '温柔的', '可爱的', '愉快的', '义气的', '认真的', '威武的', '帅气的', '传统的', '潇洒的', '漂亮的', '自然的', '专一的', '听话的', '昏睡的', '狂野的', '等待的', '搞怪的',
  1312. '幽默的', '魁梧的', '活泼的', '开心的', '高兴的', '超帅的', '留胡子的', '坦率的', '直率的', '轻松的', '痴情的', '完美的', '精明的', '无聊的', '有魅力的', '丰富的', '繁荣的',
  1313. '饱满的', '炙热的', '暴躁的', '碧蓝的', '俊逸的', '英勇的', '健忘的', '故意的', '无心的', '土豪的', '朴实的', '兴奋的', '幸福的', '淡定的', '不安的', '阔达的', '孤独的',
  1314. '独特的', '疯狂的', '时尚的', '落后的', '风趣的', '忧伤的', '大胆的', '爱笑的', '矮小的', '健康的', '合适的', '玩命的', '沉默的', '斯文的', '香蕉', '苹果', '鲤鱼', '鳗鱼',
  1315. '任性的', '细心的', '粗心的', '大意的', '甜甜的', '酷酷的', '健壮的', '英俊的', '霸气的', '阳光的', '默默的', '大力的', '孝顺的', '忧虑的', '着急的', '紧张的', '善良的',
  1316. '凶狠的', '害怕的', '重要的', '危机的', '欢喜的', '欣慰的', '满意的', '跳跃的', '诚心的', '称心的', '如意的', '怡然的', '娇气的', '无奈的', '无语的', '激动的', '愤怒的',
  1317. '美好的', '感动的', '激情的', '激昂的', '震动的', '虚拟的', '超级的', '寒冷的', '精明的', '明理的', '犹豫的', '忧郁的', '寂寞的', '奋斗的', '勤奋的', '现代的', '过时的',
  1318. '稳重的', '热情的', '含蓄的', '开放的', '无辜的', '多情的', '纯真的', '拉长的', '热心的', '从容的', '体贴的', '风中的', '曾经的', '追寻的', '儒雅的', '优雅的', '开朗的',
  1319. '外向的', '内向的', '清爽的', '文艺的', '长情的', '平常的', '单身的', '伶俐的', '高大的', '懦弱的', '柔弱的', '爱笑的', '乐观的', '耍酷的', '酷炫的', '神勇的', '年轻的',
  1320. '唠叨的', '瘦瘦的', '无情的', '包容的', '顺心的', '畅快的', '舒适的', '靓丽的', '负责的', '背后的', '简单的', '谦让的', '彩色的', '缥缈的', '欢呼的', '生动的', '复杂的',
  1321. '慈祥的', '仁爱的', '魔幻的', '虚幻的', '淡然的', '受伤的', '雪白的', '高高的', '糟糕的', '顺利的', '闪闪的', '羞涩的', '缓慢的', '迅速的', '优秀的', '聪明的', '含糊的',
  1322. '俏皮的', '淡淡的', '坚强的', '平淡的', '欣喜的', '能干的', '灵巧的', '友好的', '机智的', '机灵的', '正直的', '谨慎的', '俭朴的', '殷勤的', '虚心的', '辛勤的', '自觉的',
  1323. '无私的', '无限的', '踏实的', '老实的', '现实的', '可靠的', '务实的', '拼搏的', '个性的', '粗犷的', '活力的', '成就的', '勤劳的', '单纯的', '落寞的', '朴素的', '悲凉的',
  1324. '忧心的', '洁净的', '清秀的', '自由的', '小巧的', '单薄的', '贪玩的', '刻苦的', '干净的', '壮观的', '和谐的', '文静的', '调皮的', '害羞的', '安详的', '自信的', '端庄的',
  1325. '坚定的', '美满的', '舒心的', '温暖的', '专注的', '勤恳的', '美丽的', '腼腆的', '优美的', '甜美的', '甜蜜的', '整齐的', '动人的', '典雅的', '尊敬的', '舒服的', '妩媚的',
  1326. '秀丽的', '喜悦的', '甜美的', '彪壮的', '强健的', '大方的', '俊秀的', '聪慧的', '迷人的', '陶醉的', '悦耳的', '动听的', '明亮的', '结实的', '魁梧的', '标致的', '清脆的',
  1327. '敏感的', '光亮的', '大气的', '老迟到的', '知性的', '冷傲的', '呆萌的', '野性的', '隐形的', '笑点低的', '微笑的', '笨笨的', '难过的', '沉静的', '火星上的', '失眠的',
  1328. '安静的', '纯情的', '要减肥的', '迷路的', '烂漫的', '哭泣的', '贤惠的', '苗条的', '温婉的', '发嗲的', '会撒娇的', '贪玩的', '执着的', '眯眯眼的', '花痴的', '想人陪的',
  1329. '眼睛大的', '高贵的', '傲娇的', '心灵美的', '爱撒娇的', '细腻的', '天真的', '怕黑的', '感性的', '飘逸的', '怕孤独的', '忐忑的', '高挑的', '傻傻的', '冷艳的', '爱听歌的',
  1330. '还单身的', '怕孤单的', '懵懂的'];
  1331. $nick_name_wei = ['嚓茶', '皮皮虾', '皮卡丘', '马里奥', '小霸王', '凉面', '便当', '毛豆', '花生', '可乐', '灯泡', '哈密瓜', '野狼', '背包', '眼神', '缘分', '雪碧', '人生', '牛排',
  1332. '蚂蚁', '飞鸟', '灰狼', '斑马', '汉堡', '悟空', '巨人', '绿茶', '自行车', '保温杯', '大碗', '墨镜', '魔镜', '煎饼', '月饼', '月亮', '星星', '芝麻', '啤酒', '玫瑰',
  1333. '大叔', '小伙', '哈密瓜,数据线', '太阳', '树叶', '芹菜', '黄蜂', '蜜粉', '蜜蜂', '信封', '西装', '外套', '裙子', '大象', '猫咪', '母鸡', '路灯', '蓝天', '白云',
  1334. '星月', '彩虹', '微笑', '摩托', '板栗', '高山', '大地', '大树', '电灯胆', '砖头', '楼房', '水池', '鸡翅', '蜻蜓', '红牛', '咖啡', '机器猫', '枕头', '大船', '诺言',
  1335. '钢笔', '刺猬', '天空', '飞机', '大炮', '冬天', '洋葱', '春天', '夏天', '秋天', '冬日', '航空', '毛衣', '豌豆', '黑米', '玉米', '眼睛', '老鼠', '白羊', '帅哥', '美女',
  1336. '季节', '鲜花', '服饰', '裙子', '白开水', '秀发', '大山', '火车', '汽车', '歌曲', '舞蹈', '老师', '导师', '方盒', '大米', '麦片', '水杯', '水壶', '手套', '鞋子', '自行车',
  1337. '鼠标', '手机', '电脑', '书本', '奇迹', '身影', '香烟', '夕阳', '台灯', '宝贝', '未来', '皮带', '钥匙', '心锁', '故事', '花瓣', '滑板', '画笔', '画板', '学姐', '店员',
  1338. '电源', '饼干', '宝马', '过客', '大白', '时光', '石头', '钻石', '河马', '犀牛', '西牛', '绿草', '抽屉', '柜子', '往事', '寒风', '路人', '橘子', '耳机', '鸵鸟', '朋友',
  1339. '苗条', '铅笔', '钢笔', '硬币', '热狗', '大侠', '御姐', '萝莉', '毛巾', '期待', '盼望', '白昼', '黑夜', '大门', '黑裤', '钢铁侠', '哑铃', '板凳', '枫叶', '荷花', '乌龟',
  1340. '仙人掌', '衬衫', '大神', '草丛', '早晨', '心情', '茉莉', '流沙', '蜗牛', '战斗机', '冥王星', '猎豹', '棒球', '篮球', '乐曲', '电话', '网络', '世界', '中心', '鱼', '鸡', '狗',
  1341. '老虎', '鸭子', '雨', '羽毛', '翅膀', '外套', '火', '丝袜', '书包', '钢笔', '冷风', '八宝粥', '烤鸡', '大雁', '音响', '招牌', '胡萝卜', '冰棍', '帽子', '菠萝', '蛋挞', '香水',
  1342. '泥猴桃', '吐司', '溪流', '黄豆', '樱桃', '小鸽子', '小蝴蝶', '爆米花', '花卷', '小鸭子', '小海豚', '日记本', '小熊猫', '小懒猪', '小懒虫', '荔枝', '镜子', '曲奇', '金针菇',
  1343. '小松鼠', '小虾米', '酒窝', '紫菜', '金鱼', '柚子', '果汁', '百褶裙', '项链', '帆布鞋', '火龙果', '奇异果', '煎蛋', '唇彩', '小土豆', '高跟鞋', '戒指', '雪糕', '睫毛', '铃铛',
  1344. '手链', '香氛', '红酒', '月光', '酸奶', '银耳汤', '咖啡豆', '小蜜蜂', '小蚂蚁', '蜡烛', '棉花糖', '向日葵', '水蜜桃', '小蝴蝶', '小刺猬', '小丸子', '指甲油', '康乃馨', '糖豆',
  1345. '薯片', '口红', '超短裙', '乌冬面', '冰淇淋', '棒棒糖', '长颈鹿', '豆芽', '发箍', '发卡', '发夹', '发带', '铃铛', '小馒头', '小笼包', '小甜瓜', '冬瓜', '香菇', '小兔子',
  1346. '含羞草', '短靴', '睫毛膏', '小蘑菇', '跳跳糖', '小白菜', '草莓', '柠檬', '月饼', '百合', '纸鹤', '小天鹅', '云朵', '芒果', '面包', '海燕', '小猫咪', '龙猫', '唇膏', '鞋垫',
  1347. '羊', '黑猫', '白猫', '万宝路', '金毛', '山水', '音响', '纸飞机', '烧鹅'];
  1348. /**
  1349. * 百家姓
  1350. */
  1351. $arrXing = ['赵', '钱', '孙', '李', '周', '吴', '郑', '王', '冯', '陈', '褚', '卫', '蒋', '沈', '韩', '杨', '朱', '秦', '尤', '许', '何', '吕', '施', '张', '孔', '曹', '严', '华', '金', '魏', '陶', '姜', '戚', '谢', '邹',
  1352. '喻', '柏', '水', '窦', '章', '云', '苏', '潘', '葛', '奚', '范', '彭', '郎', '鲁', '韦', '昌', '马', '苗', '凤', '花', '方', '任', '袁', '柳', '鲍', '史', '唐', '费', '薛', '雷', '贺', '倪', '汤', '滕', '殷', '罗',
  1353. '毕', '郝', '安', '常', '傅', '卞', '齐', '元', '顾', '孟', '平', '黄', '穆', '萧', '尹', '姚', '邵', '湛', '汪', '祁', '毛', '狄', '米', '伏', '成', '戴', '谈', '宋', '茅', '庞', '熊', '纪', '舒', '屈', '项', '祝',
  1354. '董', '梁', '杜', '阮', '蓝', '闵', '季', '贾', '路', '娄', '江', '童', '颜', '郭', '梅', '盛', '林', '钟', '徐', '邱', '骆', '高', '夏', '蔡', '田', '樊', '胡', '凌', '霍', '虞', '万', '支', '柯', '管', '卢', '莫',
  1355. '柯', '房', '裘', '缪', '解', '应', '宗', '丁', '宣', '邓', '单', '杭', '洪', '包', '诸', '左', '石', '崔', '吉', '龚', '程', '嵇', '邢', '裴', '陆', '荣', '翁', '荀', '于', '惠', '甄', '曲', '封', '储', '仲', '伊',
  1356. '宁', '仇', '甘', '武', '符', '刘', '景', '詹', '龙', '叶', '幸', '司', '黎', '溥', '印', '怀', '蒲', '邰', '从', '索', '赖', '卓', '屠', '池', '乔', '胥', '闻', '莘', '党', '翟', '谭', '贡', '劳', '逄', '姬', '申',
  1357. '扶', '堵', '冉', '宰', '雍', '桑', '寿', '通', '燕', '浦', '尚', '农', '温', '别', '庄', '晏', '柴', '瞿', '阎', '连', '习', '容', '向', '古', '易', '廖', '庾', '终', '步', '都', '耿', '满', '弘', '匡', '国', '文',
  1358. '寇', '广', '禄', '阙', '东', '欧', '利', '师', '巩', '聂', '关', '荆', '司马', '上官', '欧阳', '夏侯', '诸葛', '闻人', '东方', '赫连', '皇甫', '尉迟', '公羊', '澹台', '公冶', '宗政', '濮阳', '淳于', '单于', '太叔',
  1359. '申屠', '公孙', '仲孙', '轩辕', '令狐', '徐离', '宇文', '长孙', '慕容', '司徒', '司空', '皮'];
  1360. /**
  1361. * 名
  1362. */
  1363. $arrMing = ['伟', '刚', '勇', '毅', '俊', '峰', '强', '军', '平', '保', '东', '文', '辉', '力', '明', '永', '健', '世', '广', '志', '义', '兴', '良', '海', '山', '仁', '波', '宁', '贵', '福', '生', '龙', '元', '全'
  1364. , '国', '胜', '学', '祥', '才', '发', '武', '新', '利', '清', '飞', '彬', '富', '顺', '信', '子', '杰', '涛', '昌', '成', '康', '星', '光', '天', '达', '安', '岩', '中', '茂', '进', '林', '有', '坚', '和', '彪', '博', '诚'
  1365. , '先', '敬', '震', '振', '壮', '会', '思', '群', '豪', '心', '邦', '承', '乐', '绍', '功', '松', '善', '厚', '庆', '磊', '民', '友', '裕', '河', '哲', '江', '超', '浩', '亮', '政', '谦', '亨', '奇', '固', '之', '轮', '翰'
  1366. , '朗', '伯', '宏', '言', '若', '鸣', '朋', '斌', '梁', '栋', '维', '启', '克', '伦', '翔', '旭', '鹏', '泽', '晨', '辰', '士', '以', '建', '家', '致', '树', '炎', '德', '行', '时', '泰', '盛', '雄', '琛', '钧', '冠', '策'
  1367. , '腾', '楠', '榕', '风', '航', '弘', '秀', '娟', '英', '华', '慧', '巧', '美', '娜', '静', '淑', '惠', '珠', '翠', '雅', '芝', '玉', '萍', '红', '娥', '玲', '芬', '芳', '燕', '彩', '春', '菊', '兰', '凤', '洁', '梅', '琳'
  1368. , '素', '云', '莲', '真', '环', '雪', '荣', '爱', '妹', '霞', '香', '月', '莺', '媛', '艳', '瑞', '凡', '佳', '嘉', '琼', '勤', '珍', '贞', '莉', '桂', '娣', '叶', '璧', '璐', '娅', '琦', '晶', '妍', '茜', '秋', '珊', '莎'
  1369. , '锦', '黛', '青', '倩', '婷', '姣', '婉', '娴', '瑾', '颖', '露', '瑶', '怡', '婵', '雁', '蓓', '纨', '仪', '荷', '丹', '蓉', '眉', '君', '琴', '蕊', '薇', '菁', '梦', '岚', '苑', '婕', '馨', '瑗', '琰', '韵', '融', '园'
  1370. , '艺', '咏', '卿', '聪', '澜', '纯', '毓', '悦', '昭', '冰', '爽', '琬', '茗', '羽', '希', '欣', '飘', '育', '滢', '馥', '筠', '柔', '竹', '霭', '凝', '晓', '欢', '霄', '枫', '芸', '菲', '寒', '伊', '亚', '宜', '可', '姬'
  1371. , '舒', '影', '荔', '枝', '丽', '阳', '妮', '宝', '贝', '初', '程', '梵', '罡', '恒', '鸿', '桦', '骅', '剑', '娇', '纪', '宽', '苛', '灵', '玛', '媚', '琪', '晴', '容', '睿', '烁', '堂', '唯', '威', '韦', '雯', '苇', '萱'
  1372. , '阅', '彦', '宇', '雨', '洋', '忠', '宗', '曼', '紫', '逸', '贤', '蝶', '菡', '绿', '蓝', '儿', '翠', '烟'];
  1373. $nick_name = '';
  1374. switch ($type) {
  1375. case 1:
  1376. $tou_num = rand(0, count($nick_name_tou) - 1);
  1377. $wei_num = rand(0, count($nick_name_wei) - 1);
  1378. $nick_name = $nick_name_tou[$tou_num] . $nick_name_wei[$wei_num];
  1379. break;
  1380. case 2:
  1381. $nick_name = $arrXing[mt_rand(0, count($arrXing) - 1)];
  1382. for ($i = 1; $i <= 3; $i++) {
  1383. $nick_name .= (mt_rand(0, 1) ? $arrMing[mt_rand(0, count($arrMing) - 1)] : $arrMing[mt_rand(0, count($arrMing) - 1)]);
  1384. }
  1385. break;
  1386. }
  1387. return $nick_name;
  1388. }
  1389. }
  1390. if (!function_exists('getMillisecond')) {
  1391. function getMillisecond() {
  1392. list($s1, $s2) = explode(' ', microtime());
  1393. return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
  1394. }
  1395. }
  1396. /**
  1397. * 下划线转驼峰
  1398. * @param $str
  1399. * @return array|string|string[]|null
  1400. */
  1401. function convertUnderline($str)
  1402. {
  1403. $str = preg_replace_callback('/([-_]+([a-z]{1}))/i', function($matches){
  1404. return strtoupper($matches[2]);
  1405. }, $str);
  1406. return $str;
  1407. }
  1408. /**
  1409. * 返回完整的文件地址
  1410. */
  1411. if (!function_exists('formatFileUrl')) {
  1412. function formatFileUrl($url)
  1413. {
  1414. if (empty($url)) {
  1415. return $url;
  1416. }
  1417. if (strpos($url, "https://") !== false || strpos($url, "http://") !== false) {
  1418. return $url;
  1419. }
  1420. $url = trim($url, "/");
  1421. return config("obs.obsDomain") . "/" . $url;
  1422. }
  1423. }
  1424. /**
  1425. * 是否海外版本
  1426. * @return bool
  1427. */
  1428. function isOverseasEdition()
  1429. {
  1430. return boolval(config('app.overseas_edition'));
  1431. }
  1432. /**
  1433. * 格式化时间
  1434. * @param $dateTime
  1435. * @return string
  1436. */
  1437. function formatLocaleTime($dateTime)
  1438. {
  1439. $time = strtotime($dateTime);
  1440. if (!isOverseasEdition()) {
  1441. $weekArray = ["日", "一", "二", "三", "四", "五", "六"];
  1442. return date('Y年m月d日 H时i分', $time).
  1443. ' 星期'.$weekArray[date('w', $time)];
  1444. } else {
  1445. $month = ["January","February", "March", "April", "May", "June", "July",
  1446. "August", "September", "October", "November", "December"][intval(date("m", $time))];
  1447. return date('H:i - l, d ', $time).$month.' '.
  1448. date('Y', $time).'(China, Singapore, Perth)';
  1449. }
  1450. }
  1451. //获取当前语言,包含是否国际版标识
  1452. function getLocale()
  1453. {
  1454. $isOverseas = boolval(config('app.overseas_edition'));
  1455. $siteName = 'inside';
  1456. if ($isOverseas) {
  1457. $siteName = 'overseas';
  1458. }
  1459. $translator = app('translator');
  1460. $curLang = $translator->getLocale();
  1461. return [
  1462. 'site' => $siteName,
  1463. 'language' => $curLang
  1464. ];
  1465. }
  1466. /**
  1467. * 获取站点语言
  1468. * @return string
  1469. */
  1470. function getSiteLocale()
  1471. {
  1472. return isOverseasEdition() ? 'en-us' : 'zh-cn';
  1473. }
  1474. /**
  1475. * 登录用户信息
  1476. */
  1477. function getAccessToken()
  1478. {
  1479. $tokenKey = 'inside';
  1480. if (config('app.overseas_edition')) {
  1481. $tokenKey = 'overseas';
  1482. }
  1483. $tokenKey .= '_' . config('app.global_access_token_key');
  1484. return $_COOKIE[$tokenKey] ?? '';
  1485. }
  1486. /**
  1487. * 根据id生成邀请码
  1488. */
  1489. function createInviteCode($userId, $length = 4)
  1490. {
  1491. $key = 'CUTW4JGSHKVY58QNMEP62XRZ7AFB31D9'; // key顺序不能变,用于邀请码解码用
  1492. $octal = strlen($key);
  1493. $code = '';
  1494. // 转进制
  1495. while ($userId > 0) {
  1496. $mod = $userId % $octal; // 求模
  1497. $userId = ($userId - $mod) / $octal;
  1498. $code = $key[$mod] . $code;
  1499. }
  1500. // 最小4位
  1501. return str_pad($code, $length, '0', STR_PAD_LEFT); // 不足用0补充;
  1502. }
  1503. /**
  1504. * 邀请码解码
  1505. */
  1506. function inviteCodeDecode($code)
  1507. {
  1508. $key = 'CUTW4JGSHKVY58QNMEP62XRZ7AFB31D9';
  1509. $octal = strlen($key);
  1510. if (strrpos($code, '0') !== false) {
  1511. $code = substr($code, strrpos($code, '0') + 1);
  1512. }
  1513. $code = strrev($code);
  1514. $len = strlen($code);
  1515. $userId = 0;
  1516. for ($i = 0; $i < $len; $i++) {
  1517. $userId += strpos($key, $code[$i]) * ($octal ** $i);
  1518. }
  1519. return $userId;
  1520. }