ToolServer.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. <?php
  2. namespace App\Server;
  3. use Illuminate\Support\Arr;
  4. use \Illuminate\Support\Facades\DB;
  5. use Illuminate\Support\Facades\Storage;
  6. class ToolServer
  7. {
  8. /**
  9. * curl 请求工具
  10. * @param string $method
  11. * @param string $url
  12. * @param array $params
  13. * @param bool $json
  14. * @param bool $isDecode
  15. * @return bool|mixed|string
  16. */
  17. public static function curl(string $method, string $url, array $params = [], bool $json = false, bool $isDecode = false)
  18. {
  19. $method = strtoupper($method);
  20. $ch = curl_init();
  21. curl_setopt($ch, CURLOPT_HEADER, 0);
  22. if ($method == 'GET') {
  23. $url_params = '';
  24. foreach ($params as $key => $val) {
  25. if (empty($url_params)) {
  26. $url_params .= '?';
  27. } else {
  28. $url_params .= '&';
  29. }
  30. $url_params .= $key . '=' . $val;
  31. }
  32. if (!empty($url_params)) {
  33. $url .= $url_params;
  34. }
  35. curl_setopt($ch, CURLOPT_URL, $url);
  36. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  37. } elseif ($method == 'POST') {
  38. curl_setopt($ch, CURLOPT_URL, $url);
  39. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  40. curl_setopt($ch, CURLOPT_POST, 1);
  41. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  42. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  43. if ($json == true) {
  44. $params = json_encode($params, JSON_UNESCAPED_UNICODE);
  45. $len = strlen($params);
  46. $headers = array("Content-type: application/json;charset=UTF-8","Content-Length: $len");
  47. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  48. } else {
  49. $params = http_build_query($params);
  50. }
  51. curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
  52. }
  53. $data = curl_exec($ch);
  54. curl_close($ch);
  55. if ($isDecode) {
  56. $data = json_decode($data, true);
  57. }
  58. return $data;
  59. }
  60. /**
  61. * 自动收起距离单位
  62. * @param float $distance
  63. * @return float|int|string
  64. */
  65. public static function distance(float $distance)
  66. {
  67. if ($distance == -1) {
  68. return -1;
  69. }
  70. if ($distance > 1000) {
  71. $distance = round($distance / 1000, 2) . 'km';
  72. } else {
  73. $distance .= 'm';
  74. }
  75. return $distance;
  76. }
  77. /**
  78. * 获取地址距离
  79. * @param array $from [起点坐标(经纬度),例如:array(118.012951,36.810024)]
  80. * @param array $to [终点坐标(经纬度)]
  81. * @param bool $km 是否以公里为单位 false:米 true:公里(千米)
  82. * @param int $decimal $decimal 精度 保留小数位数
  83. * @return int|string 距离数值
  84. */
  85. public static function getDistance(array $from, array $to, bool $km = true, int $decimal = 2)
  86. {
  87. sort($from);
  88. sort($to);
  89. $EARTH_RADIUS = 6370.996; // 地球半径系数
  90. $distance = $EARTH_RADIUS * 2 * asin(sqrt(pow(sin(($from[0] * pi() / 180 - $to[0] * pi() / 180) / 2), 2) + cos($from[0] * pi() / 180) * cos($to[0] * pi() / 180) * pow(sin(($from[1] * pi() / 180 - $to[1] * pi() / 180) / 2), 2))) * 1000;
  91. if ($km) {
  92. $distance = $distance / 1000;
  93. }
  94. return round($distance, $decimal);
  95. }
  96. /**
  97. * 加密(可对接java)
  98. * @param array $data
  99. * @param string $key
  100. * @param string $secret
  101. * @return string
  102. */
  103. public static function encodeOld(array $data, string $key, string $secret)
  104. {
  105. $plaintext = urldecode(http_build_query($data)) . '@';
  106. $key = strtoupper(md5($key . $secret));
  107. $size = 16;
  108. $iv = str_repeat("\0", $size);
  109. $padding = $size - strlen($plaintext) % $size;
  110. $plaintext .= str_repeat(chr($padding), $padding);
  111. $encrypted = openssl_encrypt($plaintext, 'AES-192-CBC', base64_decode($key), OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
  112. return base64_encode($encrypted);
  113. }
  114. /**
  115. * 加密
  116. * @param array $data
  117. * @param string $key
  118. * @return string
  119. */
  120. public static function encode(array $data, string $key)
  121. {
  122. //数据集合转化字符串 再加个 @
  123. $plaintext = urldecode(http_build_query($data)) . '@';
  124. //md5 加密 key
  125. $key_md5 = $key;
  126. $size = 16;
  127. //生成 16 位偏移量
  128. //$iv = str_repeat("\0", $size);
  129. $iv = "0987654321098765";
  130. // 使用 PKCS5Padding 填充
  131. $padding = $size - strlen($plaintext) % $size;
  132. $plaintext .= str_repeat(chr($padding), $padding);
  133. $encrypted = openssl_encrypt($plaintext, 'AES-128-CBC', $key_md5, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
  134. return base64_encode($encrypted);
  135. }
  136. public static function encodeStr(string $data, string $key)
  137. {
  138. //数据集合转化字符串 再加个 @
  139. $plaintext = $data . '@';
  140. //md5 加密 key
  141. $key_md5 = $key;
  142. $size = 16;
  143. //生成 16 位偏移量
  144. $iv = str_repeat("\0", $size);
  145. //$iv = "0987654321098765";
  146. // 使用 PKCS5Padding 填充
  147. $padding = $size - strlen($plaintext) % $size;
  148. $plaintext .= str_repeat(chr($padding), $padding);
  149. $encrypted = openssl_encrypt($plaintext, 'AES-128-CBC', $key_md5, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
  150. return base64_encode($encrypted);
  151. }
  152. /**
  153. * 解密(可对接java)
  154. * @param string $content
  155. * @param string $key
  156. * @return array
  157. */
  158. public static function decode(string $content, string $key)
  159. {
  160. $key_md5 = $key;
  161. $size = 16;
  162. //$iv = str_repeat("\0", $size);
  163. $iv = "0987654321098765";
  164. $decrypted = openssl_decrypt(base64_decode($content), 'AES-128-CBC', $key_md5, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
  165. $data_decode = explode('@', $decrypted);
  166. //$data = [];
  167. //parse_str($data_decode[0], $data);
  168. return json_decode($data_decode[0], true);
  169. }
  170. /**
  171. * 解密(php)
  172. * @param string $content
  173. * @param string $key
  174. * @param string $secret
  175. * @return mixed
  176. */
  177. public static function decodeOld(string $content, string $key, string $secret)
  178. {
  179. $key = strtoupper(md5($key . $secret));
  180. $size = 16;
  181. $iv = str_repeat("\0", $size);
  182. $decrypted = openssl_decrypt(base64_decode($content), 'AES-192-CBC', base64_decode($key), OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
  183. $data_decode = explode('@', $decrypted);
  184. //$data = [];
  185. //parse_str($data_decode[0], $data);
  186. //return $data;
  187. return json_decode($data_decode[0], true);
  188. }
  189. public static function toStr($bytes)
  190. {
  191. $str = '';
  192. foreach ($bytes as $ch) {
  193. //dd(chr($ch));
  194. try {
  195. $str .= chr($ch);
  196. } catch (\Exception $e) {
  197. dd(chr($ch));
  198. }
  199. }
  200. return $str;
  201. }
  202. /**
  203. * 签名算法
  204. * @param array $params
  205. * @param string $secret
  206. * @return array
  207. */
  208. public static function sign(array $params, string $secret)
  209. {
  210. $p = ksort($params);
  211. $str = '';
  212. if ($p) {
  213. foreach ($params as $key => $items) {
  214. $str .= "{$key}";
  215. $str .= "=";
  216. $str .= "{$items}";
  217. $str .= "&";
  218. }
  219. }
  220. $string = substr($str, 0, -1);
  221. //$string = "appKey=$this->appKey&nonce=$this->nonce&timestamp=$this->timestamp";
  222. $stringSignTemp = "$string&secret=$secret";
  223. //echo $stringSignTemp;
  224. $sign = strtoupper(MD5($stringSignTemp));
  225. $params['sign'] = $sign;
  226. return $params;
  227. }
  228. /**
  229. *
  230. * @param string $key
  231. * @param string $value
  232. * @return array
  233. */
  234. public static function user_admin_config($key = null, $value = null)
  235. {
  236. $session = session();
  237. if (! $config = $session->get('admin.config')) {
  238. $config = config('admin');
  239. $config['lang'] = config('app.locale');
  240. }
  241. if (is_array($key)) {
  242. // 保存
  243. foreach ($key as $k => $v) {
  244. Arr::set($config, $k, $v);
  245. }
  246. $session->put('admin.config', $config);
  247. return;
  248. }
  249. if ($key === null) {
  250. return $config;
  251. }
  252. return Arr::get($config, $key, $value);
  253. }
  254. /**
  255. * 生成随机码
  256. * @return string
  257. */
  258. public static function create_invite_code() {
  259. $code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  260. $rand = $code[rand(0,25)]
  261. .strtoupper(dechex(date('m')))
  262. .date('d')
  263. .substr(time(),-5)
  264. .substr(microtime(),2,5)
  265. .sprintf('%02d',rand(0,99));
  266. for(
  267. $a = md5( $rand, true ),
  268. $s = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  269. $d = '',
  270. $f = 0;
  271. $f < 6;
  272. $g = ord( $a[ $f ] ),
  273. $d .= $s[ ( $g ^ ord( $a[ $f + 8 ] ) ) - $g & 0x1F ],
  274. $f++
  275. );
  276. return $d;
  277. }
  278. /**
  279. * 时间格式化(时间戳)
  280. * @param $ptime
  281. * @return false|string
  282. */
  283. public static function uc_time_ago($ptime)
  284. {
  285. date_default_timezone_set('PRC');
  286. $etime = time() - $ptime;
  287. switch ($etime) {
  288. case $etime <= 60:
  289. $msg = '刚刚';
  290. break;
  291. case $etime > 60 && $etime <= 60 * 60:
  292. $msg = floor($etime / 60) . '分钟前';
  293. break;
  294. case $etime > 60 * 60 && $etime <= 24 * 60 * 60:
  295. $msg = date('Ymd', $ptime) == date('Ymd', time()) ? '今天 ' . date('H:i', $ptime) : '昨天 ' . date('H:i', $ptime);
  296. break;
  297. case $etime > 24 * 60 * 60 && $etime <= 2 * 24 * 60 * 60:
  298. $msg = date('Ymd', $ptime) + 1 == date('Ymd', time()) ? '昨天 ' . date('H:i', $ptime) : '前天 ' . date('H:i', $ptime);
  299. break;
  300. case $etime > 2 * 24 * 60 * 60 && $etime <= 12 * 30 * 24 * 60 * 60:
  301. $msg = date('Y', $ptime) == date('Y', time()) ? date('m-d H:i', $ptime) : date('Y-m-d H:i', $ptime);
  302. break;
  303. default:
  304. $msg = date('Y-m-d H:i', $ptime);
  305. }
  306. return $msg;
  307. }
  308. /**
  309. * 获取IP地址归属地
  310. * @param $ip
  311. * @return string
  312. */
  313. public static function get_ip_address($ip)
  314. {
  315. if ('127.0.0.1' == $ip) return 'Localhost';
  316. $url = 'http://ip.taobao.com/service/getIpInfo.php?ip=' . $ip;
  317. $ch = curl_init($url);
  318. curl_setopt($ch, CURLOPT_TIMEOUT, 10);
  319. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 获取数据返回
  320. $location = curl_exec($ch);
  321. $location = json_decode($location, true);
  322. curl_close($ch);
  323. if (false != $location && 0 === $location['code']) {
  324. return $location['data']['region'] . $location['data']['city'] . $location['data']['county'] . '・' . $location['data']['isp'];
  325. } else {
  326. return 'unknown';
  327. }
  328. }
  329. /**
  330. * 递归查询获取分类树结构
  331. * @param $data
  332. * @param int $pid
  333. * @param int $level
  334. * @param array $tree
  335. * @param string $pidField
  336. * @param string $showField
  337. * @return array
  338. */
  339. public static function get_tree_list(&$data, $pid = 0, $level = 0, &$tree = [], $pidField = 'pid', $showField = 'name')
  340. {
  341. foreach ($data as $key => &$value) {
  342. if ($value[$pidField] == $pid) {
  343. $value['level'] = $level;
  344. $value['level'] && $value[$showField] = '&nbsp;' . $value[$showField];
  345. $value[$showField] = str_repeat('ㅡ', $value['level']) . $value[$showField];
  346. $tree[] = $value;
  347. unset($data[$key]);
  348. self::get_tree_list($data, $value['id'], $level + 1, $tree);
  349. }
  350. }
  351. unset($value);
  352. return $tree;
  353. }
  354. /**
  355. * 递归查询获取分类树结构带child
  356. * @param $data
  357. * @param int $pid
  358. * @param int $level
  359. * @param string $pidField
  360. * @return array
  361. */
  362. public static function get_tree_list_with_child(&$data, $pid = 0, $level = 0, $pidField = 'pid')
  363. {
  364. $tree = [];
  365. foreach ($data as $key => &$value) {
  366. if ($value[$pidField] == $pid) {
  367. $value['level'] = $level;
  368. $value['child'] = self::get_tree_list_with_child($data, $value['id'], $level + 1);
  369. $tree[] = $value;
  370. unset($data[$key]);
  371. }
  372. }
  373. unset($value);
  374. return $tree;
  375. }
  376. /**
  377. * 打印sql语句,在sql语句之前调用
  378. */
  379. public static function dump_sql()
  380. {
  381. \DB::listen(function ($query) {
  382. $bindings = $query->bindings;
  383. $i = 0;
  384. $rawSql = preg_replace_callback('/\?/', function ($matches) use ($bindings, &$i) {
  385. $item = isset($bindings[$i]) ? $bindings[$i] : $matches[0];
  386. $i++;
  387. return gettype($item) == 'string' ? "'$item'" : $item;
  388. }, $query->sql);
  389. echo $rawSql . "\n<br /><br />\n";
  390. });
  391. }
  392. public static function create_guid($namespace = null)
  393. {
  394. static $guid = '';
  395. $uid = uniqid("", true);
  396. $data = $namespace;
  397. $data .= $_SERVER ['REQUEST_TIME']; // 请求那一刻的时间戳
  398. $data .= $_SERVER ['HTTP_USER_AGENT']; // 获取访问者在用什么操作系统
  399. $data .= $_SERVER ['SERVER_ADDR']; // 服务器IP
  400. $data .= $_SERVER ['SERVER_PORT']; // 端口号
  401. $data .= $_SERVER ['REMOTE_ADDR']; // 远程IP
  402. $data .= $_SERVER ['REMOTE_PORT']; // 端口信息
  403. $hash = strtoupper(hash('ripemd128', $uid . $guid . md5($data)));
  404. $guid = substr($hash, 0, 8);
  405. return $guid;
  406. }
  407. public static function create_order_number()
  408. {
  409. return date('Ymd') . str_pad(mt_rand(1, 999999), 6, '0', STR_PAD_LEFT);
  410. }
  411. /**
  412. * curl 请求
  413. * @param $url
  414. * @param null $header
  415. * @param null $data
  416. * @return mixed
  417. */
  418. public static function curlRequest($url, $header = null, $data = null)
  419. {
  420. $ch = curl_init();
  421. curl_setopt($ch, CURLOPT_URL, $url);
  422. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  423. curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
  424. curl_setopt($ch, CURLOPT_HEADER, 1);
  425. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  426. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  427. if ($data) {
  428. curl_setopt($ch, CURLOPT_POST, 1);
  429. curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  430. }
  431. if ($header) {
  432. curl_setopt($ch, CURLOPT_HEADER, $header);
  433. }
  434. $ret = curl_exec($ch);
  435. curl_close($ch);
  436. return $ret;
  437. }
  438. /**
  439. * 数字金额转换成中文大写金额的函数
  440. * @param $num
  441. * @return string
  442. */
  443. public static function cny($num)
  444. {
  445. $c1 = "零壹贰叁肆伍陆柒捌玖";
  446. $c2 = "分角元拾佰仟万拾佰仟亿";
  447. $num = round($num, 2);
  448. $num = $num * 100;
  449. if (strlen($num) > 10) {
  450. return "数据太长,没有这么大的钱吧,检查下";
  451. }
  452. $i = 0;
  453. $c = "";
  454. while (1) {
  455. if ($i == 0) {
  456. $n = substr($num, strlen($num) - 1, 1);
  457. } else {
  458. $n = $num % 10;
  459. }
  460. $p1 = substr($c1, 3 * $n, 3);
  461. $p2 = substr($c2, 3 * $i, 3);
  462. if ($n != '0' || ($n == '0' && ($p2 == '亿' || $p2 == '万' || $p2 == '元'))) {
  463. $c = $p1 . $p2 . $c;
  464. } else {
  465. $c = $p1 . $c;
  466. }
  467. $i = $i + 1;
  468. $num = $num / 10;
  469. $num = (int)$num;
  470. if ($num == 0) {
  471. break;
  472. }
  473. }
  474. $j = 0;
  475. $slen = strlen($c);
  476. while ($j < $slen) {
  477. $m = substr($c, $j, 6);
  478. if ($m == '零元' || $m == '零万' || $m == '零亿' || $m == '零零') {
  479. $left = substr($c, 0, $j);
  480. $right = substr($c, $j + 3);
  481. $c = $left . $right;
  482. $j = $j - 3;
  483. $slen = $slen - 3;
  484. }
  485. $j = $j + 3;
  486. }
  487. if (substr($c, strlen($c) - 3, 3) == '零') {
  488. $c = substr($c, 0, strlen($c) - 3);
  489. }
  490. if (empty($c)) {
  491. return "零元整";
  492. } else {
  493. return $c . "整";
  494. }
  495. }
  496. /**
  497. * 路径助手函数
  498. * @param $url
  499. * @param null $disk_name
  500. * @param false $temp
  501. * @param null|DateTimeInterface $expiration
  502. * @return string|null
  503. */
  504. public static function valid_url($url, $disk_name = null, $temp = false, $expiration = null)
  505. {
  506. if (is_null($url)) {
  507. return null;
  508. }
  509. if (filter_var($url, FILTER_VALIDATE_URL)) {
  510. return $url;
  511. }
  512. if ($temp) {
  513. $expiration = $expiration ?: now()->addMinutes(30);
  514. return Storage::disk($disk_name)->temporaryUrl($url, $expiration);
  515. }
  516. return Storage::disk($disk_name)->url($url);
  517. }
  518. }