helpers.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. <?php
  2. /*
  3. * This file is part of the Jiannei/lumen-api-starter.
  4. *
  5. * (c) Jiannei <longjian.huang@foxmail.com>
  6. *
  7. * This source file is subject to the MIT license that is bundled
  8. * with this source code in the file LICENSE.
  9. */
  10. use App\Repositories\Enums\ModelStatusEnum;
  11. use Carbon\Carbon;
  12. use Illuminate\Support\Arr;
  13. function str2arr($str, $glue = ',')
  14. {
  15. return array_filter(array_unique(explode($glue, $str)));
  16. }
  17. function arr2str($arr, $glue = ',')
  18. {
  19. return implode($glue, array_unique(Arr::wrap($arr)));
  20. }
  21. function str2arr0($str, $glue = ',')
  22. {
  23. return explode($glue, $str);
  24. }
  25. function arr2str0($arr, $glue = ',')
  26. {
  27. return implode($glue, (Arr::wrap($arr)));
  28. }
  29. function php2js($arr)
  30. {
  31. return json_encode($arr, true);
  32. }
  33. function js2php($json)
  34. {
  35. return json_decode($json, true);
  36. }
  37. /**
  38. * 取数组的值
  39. * @param $key
  40. * @param $arr
  41. * @param string $default
  42. * @return mixed|string
  43. * Author: Mead
  44. */
  45. function get_arr_val($key, $arr = [], $default = '')
  46. {
  47. if (array_key_exists($key, $arr) && $arr[$key] != null) {
  48. return $arr[$key];
  49. }
  50. return $default;
  51. }
  52. /**
  53. * 路径转地址
  54. * @param $path
  55. * @param string $disk
  56. * @return mixed
  57. * Author: Mead
  58. */
  59. function path_to_url($path, $disk = 'public')
  60. {
  61. if (empty($path)) return null;
  62. // 如果 image 字段本身就已经是完整的 url 就直接返回
  63. if (\Illuminate\Support\Str::startsWith($path, ['http://', 'https://'])) {
  64. return $path;
  65. }
  66. return \Illuminate\Support\Facades\Storage::disk($disk)->url($path);
  67. }
  68. function is_user_login()
  69. {
  70. return auth('api')->check();
  71. }
  72. function login_user()
  73. {
  74. return auth('api')->user();
  75. }
  76. function login_admin()
  77. {
  78. return auth('admins')->user();
  79. }
  80. function login_user_id()
  81. {
  82. return auth('api')->id();
  83. }
  84. function login_admin_id()
  85. {
  86. return auth('admins')->id();
  87. }
  88. function is_admin_login()
  89. {
  90. return auth('admins')->check();
  91. }
  92. /**
  93. * 数组转树状
  94. * @param array $data
  95. * @param string $primary
  96. * @param string $parent
  97. * @param string $children
  98. * @return array
  99. * Author: Mead
  100. */
  101. function toTree($data = [], $primary = 'id', $parent = 'parent_id', $children = 'children')
  102. {
  103. if (!isset($data[0][$parent])) {
  104. return [];
  105. }
  106. $items = array();
  107. // $pids = [];
  108. foreach ($data as $v) {
  109. $items[$v[$primary]] = $v;
  110. // $pids[] = $v[$parent];
  111. }
  112. $tree = array();
  113. foreach ($items as &$item) {
  114. // if (in_array($item['id'], $pids)) {
  115. // $item['is_base'] = false;
  116. // } else {
  117. // $item['is_base'] = true;
  118. // }
  119. if (isset($items[$item[$parent]])) {
  120. $items[$item[$parent]][$children][] = &$items[$item[$primary]];
  121. } else {
  122. $tree[] = &$items[$item[$primary]];
  123. }
  124. }
  125. return $tree;
  126. }
  127. /**
  128. * 二维数组根据某个字段排序
  129. * @param array $array 要排序的数组
  130. * @param string $keys 要排序的键字段
  131. * @param string $sort 排序类型 SORT_ASC SORT_DESC
  132. * @return array 排序后的数组
  133. */
  134. function arraySort($array, $keys, $sort = SORT_DESC)
  135. {
  136. $keysValue = [];
  137. foreach ($array as $k => $v) {
  138. $keysValue[$k] = $v[$keys];
  139. }
  140. array_multisort($keysValue, $sort, $array);
  141. return $array;
  142. }
  143. function match_chinese($chars, $encoding = 'utf8')
  144. {
  145. $pattern = ($encoding == 'utf8') ? '/[\x{4e00}-\x{9fa5}a-zA-Z0-9_.]/u' : '/[\x80-\xFF]/';
  146. preg_match_all($pattern, $chars, $result);
  147. $temp = join('', $result[0]);
  148. return $temp;
  149. }
  150. function arr_str($arr)
  151. {
  152. return '-' . arr2str($arr, '-') . '-';
  153. }
  154. function str_arr($str)
  155. {
  156. return str2arr(trim($str, '-'), '-');
  157. }
  158. function wechat_fee($money)
  159. {
  160. $m = (int)($money * 100);
  161. if (login_admin_id() > 3) {
  162. if ($money <= 0) {
  163. return 1;
  164. }
  165. }
  166. return $m;
  167. }
  168. function arr2type($arr)
  169. {
  170. return '-' . arr2str($arr, '-') . '-';
  171. }
  172. function type2arr($str)
  173. {
  174. return str2arr(trim($str, '-'), '-');
  175. }
  176. function T($key)
  177. {
  178. if (\Illuminate\Support\Facades\App::getLocale() == 'zh_CN') {
  179. return __("messages.{$key}");
  180. } else {
  181. return __($key);
  182. }
  183. }
  184. if (!function_exists('config_path')) {
  185. /**
  186. * Get the configuration path.
  187. *
  188. * @param string $path
  189. * @return string
  190. */
  191. function config_path($path = '')
  192. {
  193. return app()->basePath() . '/config' . ($path ? '/' . $path : $path);
  194. }
  195. }
  196. /**
  197. * 秒数转时间
  198. * @param $sec
  199. * @return string
  200. * Author: Mead
  201. */
  202. function sec2time($sec)
  203. {
  204. $mes = '';
  205. if ($sec >= 3600) {
  206. $hours = str_pad(floor($sec / 3600), 2, "0", STR_PAD_LEFT);
  207. $sec = ($sec % 3600);
  208. $mes .= "{$hours}:";
  209. }
  210. if ($sec >= 60) {
  211. $minutes = str_pad(floor($sec / 60), 2, "0", STR_PAD_LEFT);;
  212. $sec = ($sec % 60);
  213. $mes .= "{$minutes}:";
  214. } else {
  215. $mes .= "00:";
  216. }
  217. $seconds = str_pad(floor($sec), 2, "0", STR_PAD_LEFT);;
  218. $mes .= "{$seconds}";
  219. return $mes;
  220. }
  221. /**
  222. * 字符为空
  223. * @return string
  224. * Author: Mead
  225. */
  226. function str_is_null()
  227. {
  228. return '--';
  229. }
  230. /**
  231. * 检查密码
  232. * @param $password
  233. * @return bool|string
  234. * Author: Mead
  235. */
  236. function check_password($password, $reBool = false)
  237. {
  238. $score = 0;
  239. $str = $password;
  240. $num = 0;
  241. if (preg_match("/[0-9]+/", $str)) {
  242. $score++;
  243. $num++;
  244. }
  245. if (preg_match("/[0-9]{3,}/", $str)) {
  246. $score++;
  247. }
  248. if (preg_match("/[a-z]+/", $str)) {
  249. $score++;
  250. $num++;
  251. }
  252. if (preg_match("/[a-z]{3,}/", $str)) {
  253. $score++;
  254. }
  255. if (preg_match("/[A-Z]+/", $str)) {
  256. $score++;
  257. $num++;
  258. }
  259. if (preg_match("/[A-Z]{3,}/", $str)) {
  260. $score++;
  261. }
  262. if (preg_match("/[_|\-|+|=|*|!|@|#|$|%|^|&|(|)]+/", $str)) {
  263. $score += 2;
  264. $num++;
  265. }
  266. if (preg_match("/[_|\-|+|=|*|!|@|#|$|%|^|&|(|)]{3,}/", $str)) {
  267. $score++;
  268. }
  269. if (strlen($str) >= 10) {
  270. $score++;
  271. }
  272. if ($reBool) {
  273. if ($score < 4) return false;
  274. if ($num < 2) return false;
  275. return true;
  276. }
  277. $msg = false;
  278. if ($score < 4) {
  279. $msg = '密码太简单!';
  280. }
  281. if ($num < 2) {
  282. $msg = '密码必须包含数字、字母、符号两种类型!';
  283. }
  284. return $msg;
  285. }
  286. /**
  287. * 获取登录ip
  288. * @return array|false|mixed|string
  289. * Author: Mead
  290. */
  291. function getClientIp()
  292. {
  293. if (getenv('HTTP_CLIENT_IP')) {
  294. $ip = getenv('HTTP_CLIENT_IP');
  295. }
  296. if (getenv('HTTP_X_REAL_IP')) {
  297. $ip = getenv('HTTP_X_REAL_IP');
  298. } elseif (getenv('HTTP_X_FORWARDED_FOR')) {
  299. $ip = getenv('HTTP_X_FORWARDED_FOR');
  300. $ips = explode(',', $ip);
  301. $ip = $ips[0];
  302. } elseif (getenv('REMOTE_ADDR')) {
  303. $ip = getenv('REMOTE_ADDR');
  304. } else {
  305. $ip = '0.0.0.0';
  306. }
  307. return $ip;
  308. }
  309. /**
  310. * 二维数组去重
  311. * @param $arr
  312. * @param $key
  313. * @return array
  314. */
  315. function array_unset_tt($arr = [], $key = null)
  316. {
  317. //建立一个目标数组
  318. $res = array();
  319. foreach ($arr as $value) {
  320. //查看有没有重复项
  321. if (isset($res[$value[$key]])) {
  322. unset($value[$key]);
  323. } else {
  324. $res[$value[$key]] = $value;
  325. }
  326. }
  327. return array_values($res);
  328. }
  329. /**
  330. * 获取控制器的方法
  331. * @return array
  332. */
  333. function getControllerAndFunction()
  334. {
  335. $routeInfo = app('request')->route()[1]['uses'];
  336. list($class, $method) = explode('@', $routeInfo);
  337. $module = 'admin';
  338. if (strpos($class, "\\Api\\") !== false) {
  339. $module = 'api';
  340. }
  341. $class = substr(strrchr($class, '\\'), 1);
  342. return ['controller' => $class, 'method' => $method, 'module' => $module];
  343. }
  344. /**
  345. * 删除空格「mead」
  346. * @param $str
  347. * @return array|string|string[]
  348. */
  349. function rk($str)
  350. {
  351. return str_replace(" ", '', $str);
  352. }
  353. /**
  354. * 获取值
  355. * @param $val
  356. * @param $d
  357. * @return mixed|string
  358. */
  359. function getVal($val, $d = '')
  360. {
  361. return isset($val) ? $val : $d;
  362. }
  363. /**
  364. * 异常处理
  365. * @param Exception $exception
  366. * @param $msg
  367. * @return void
  368. */
  369. function exception(\Exception $exception, $msg = '操作失败')
  370. {
  371. \Illuminate\Support\Facades\Log::error($exception);
  372. if (config('app.env') == 'production') abort(\App\Repositories\Enums\ResponseCodeEnum::SERVICE_OPERATION_ERROR, $msg);
  373. abort(\App\Repositories\Enums\ResponseCodeEnum::SERVICE_OPERATION_ERROR, $exception->getMessage());
  374. }
  375. /**
  376. * 解析身份证号
  377. * @param $card_id
  378. * @return array
  379. */
  380. function parse_card_id($card_id)
  381. {
  382. $sex_val = (int)substr($card_id, 16, 1);
  383. $sex = $sex_val % 2 === 0 ? 2 : 1;
  384. $bir = substr($card_id, 6, 8);
  385. $year = (int)substr($bir, 0, 4);
  386. $month = (int)substr($bir, 4, 2);
  387. $day = (int)substr($bir, 6, 2);
  388. $birthday = $year . "-" . $month . "-" . $day;
  389. $area_key = substr($card_id, 0, 6);
  390. // $address = \App\Repositories\Models\Base\Area::byCodeGetAreas($area_key);
  391. $age = \Illuminate\Support\Carbon::parse($birthday)->diffInYears();
  392. return [
  393. 'sex' => $sex,
  394. 'age' => $age,
  395. 'birthday' => $birthday,
  396. 'address' => [
  397. 'province' => substr($area_key, 0, 2) . '0000',
  398. 'city' => substr($area_key, 0, 4) . '00',
  399. 'area' => $area_key,
  400. ],
  401. ];
  402. }
  403. /**
  404. * 科学计数转数值
  405. * @param $number
  406. * @return array|mixed|string|string[]|null
  407. */
  408. function scientific_number_to_normal($number)
  409. {
  410. if (stripos($number, 'e') === false) {
  411. //判断是否为科学计数法
  412. return $number;
  413. }
  414. if (!preg_match(
  415. "/^([\\d.]+)[eE]([\\d\\-\\+]+)$/",
  416. str_replace(array(" ", ","), "", trim($number)), $matches)
  417. ) {
  418. //提取科学计数法中有效的数据,无法处理则直接返回
  419. return $number;
  420. }
  421. //对数字前后的0和点进行处理,防止数据干扰,实际上正确的科学计数法没有这个问题
  422. $data = preg_replace(array("/^[0]+/"), "", rtrim($matches[1], "0."));
  423. $length = (int)$matches[2];
  424. if ($data[0] == ".") {
  425. //由于最前面的0可能被替换掉了,这里是小数要将0补齐
  426. $data = "0{$data}";
  427. }
  428. //这里有一种特殊可能,无需处理
  429. if ($length == 0) {
  430. return $data;
  431. }
  432. //记住当前小数点的位置,用于判断左右移动
  433. $dot_position = strpos($data, ".");
  434. if ($dot_position === false) {
  435. $dot_position = strlen($data);
  436. }
  437. //正式数据处理中,是不需要点号的,最后输出时会添加上去
  438. $data = str_replace(".", "", $data);
  439. if ($length > 0) {
  440. //如果科学计数长度大于0
  441. //获取要添加0的个数,并在数据后面补充
  442. $repeat_length = $length - (strlen($data) - $dot_position);
  443. if ($repeat_length > 0) {
  444. $data .= str_repeat('0', $repeat_length);
  445. }
  446. //小数点向后移n位
  447. $dot_position += $length;
  448. $data = ltrim(substr($data, 0, $dot_position), "0") . "." . substr($data, $dot_position);
  449. } elseif ($length < 0) {
  450. //当前是一个负数
  451. //获取要重复的0的个数
  452. $repeat_length = abs($length) - $dot_position;
  453. if ($repeat_length > 0) {
  454. //这里的值可能是小于0的数,由于小数点过长
  455. $data = str_repeat('0', $repeat_length) . $data;
  456. }
  457. $dot_position += $length;//此处length为负数,直接操作
  458. if ($dot_position < 1) {
  459. //补充数据处理,如果当前位置小于0则表示无需处理,直接补小数点即可
  460. $data = ".{$data}";
  461. } else {
  462. $data = substr($data, 0, $dot_position) . "." . substr($data, $dot_position);
  463. }
  464. }
  465. if ($data[0] == ".") {
  466. //数据补0
  467. $data = "0{$data}";
  468. }
  469. return trim($data, ".");
  470. }
  471. /**
  472. * 获取设备类型
  473. * @return array|string|null
  474. */
  475. function device_type()
  476. {
  477. return strtolower(request()->header('device', 'pc'));
  478. }
  479. /**
  480. * 是否为手机端
  481. * @return bool
  482. */
  483. function is_mobile()
  484. {
  485. $type = request()->header('device', 'pc');
  486. return in_array($type, ['h5', 'weapp']);
  487. }
  488. /**
  489. * 是否为PC端
  490. * @return bool
  491. */
  492. function is_pc()
  493. {
  494. $type = request()->header('device', 'pc');
  495. return ($type === 'pc');
  496. }
  497. /**
  498. * 是否为 Api 路由
  499. * @return bool
  500. */
  501. function isApi()
  502. {
  503. // $con = getControllerAndFunction();
  504. // if ($con['module'] == 'api') {
  505. // return true;
  506. // }
  507. // return false;
  508. return isApiModule();
  509. }
  510. function isAdmin()
  511. {
  512. // $con = getControllerAndFunction();
  513. // if ($con['module'] == 'admin') {
  514. // return true;
  515. // }
  516. // return false;
  517. return isAdminModule();
  518. }
  519. /**
  520. * 是否为后台模块
  521. * @return bool
  522. */
  523. function isAdminModule()
  524. {
  525. $routeInfo = app('request')->route()[1]['uses'];
  526. $module = false;
  527. if (strpos($routeInfo, "\Admin\\") !== false) $module = true;
  528. return $module;
  529. }
  530. function isApiModule()
  531. {
  532. $routeInfo = app('request')->route()[1]['uses'];
  533. $module = false;
  534. if (strpos($routeInfo, "\Api\\") !== false) $module = true;
  535. return $module;
  536. }
  537. /**
  538. * 获取配置参数
  539. * @param $code
  540. * @return string|mixed
  541. */
  542. function byCodeGetSetting($code)
  543. {
  544. return \App\Repositories\Models\Base\Setting::byCodeGetSetting($code);
  545. }