common.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. <?php
  2. // 公共助手函数
  3. use Symfony\Component\VarExporter\VarExporter;
  4. use think\exception\HttpResponseException;
  5. use think\Response;
  6. use think\Db;
  7. if (!function_exists('__')) {
  8. /**
  9. * 获取语言变量值
  10. * @param string $name 语言变量名
  11. * @param array $vars 动态变量值
  12. * @param string $lang 语言
  13. * @return mixed
  14. */
  15. function __($name, $vars = [], $lang = '')
  16. {
  17. if (is_numeric($name) || !$name) {
  18. return $name;
  19. }
  20. if (!is_array($vars)) {
  21. $vars = func_get_args();
  22. array_shift($vars);
  23. $lang = '';
  24. }
  25. return \think\Lang::get($name, $vars, $lang);
  26. }
  27. }
  28. if (!function_exists('format_bytes')) {
  29. /**
  30. * 将字节转换为可读文本
  31. * @param int $size 大小
  32. * @param string $delimiter 分隔符
  33. * @param int $precision 小数位数
  34. * @return string
  35. */
  36. function format_bytes($size, $delimiter = '', $precision = 2)
  37. {
  38. $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
  39. for ($i = 0; $size >= 1024 && $i < 6; $i++) {
  40. $size /= 1024;
  41. }
  42. return round($size, $precision) . $delimiter . $units[$i];
  43. }
  44. }
  45. if (!function_exists('datetime')) {
  46. /**
  47. * 将时间戳转换为日期时间
  48. * @param int $time 时间戳
  49. * @param string $format 日期时间格式
  50. * @return string
  51. */
  52. function datetime($time, $format = 'Y-m-d H:i:s')
  53. {
  54. $time = is_numeric($time) ? $time : strtotime($time);
  55. return date($format, $time);
  56. }
  57. }
  58. if (!function_exists('human_date')) {
  59. /**
  60. * 获取语义化时间
  61. * @param int $time 时间
  62. * @param int $local 本地时间
  63. * @return string
  64. */
  65. function human_date($time, $local = null)
  66. {
  67. return \fast\Date::human($time, $local);
  68. }
  69. }
  70. if (!function_exists('cdnurl')) {
  71. /**
  72. * 获取上传资源的CDN的地址
  73. * @param string $url 资源相对地址
  74. * @param boolean $domain 是否显示域名 或者直接传入域名
  75. * @return string
  76. */
  77. function cdnurl($url, $domain = false)
  78. {
  79. $regex = "/^((?:[a-z]+:)?\/\/|data:image\/)(.*)/i";
  80. $cdnurl = \think\Config::get('upload.cdnurl');
  81. $url = preg_match($regex, $url) || ($cdnurl && stripos($url, $cdnurl) === 0) ? $url : $cdnurl . $url;
  82. if ($domain && !preg_match($regex, $url)) {
  83. $domain = is_bool($domain) ? request()->domain() : $domain;
  84. $url = $domain . $url;
  85. }
  86. return $url;
  87. }
  88. }
  89. if (!function_exists('is_really_writable')) {
  90. /**
  91. * 判断文件或文件夹是否可写
  92. * @param string $file 文件或目录
  93. * @return bool
  94. */
  95. function is_really_writable($file)
  96. {
  97. if (DIRECTORY_SEPARATOR === '/') {
  98. return is_writable($file);
  99. }
  100. if (is_dir($file)) {
  101. $file = rtrim($file, '/') . '/' . md5(mt_rand());
  102. if (($fp = @fopen($file, 'ab')) === false) {
  103. return false;
  104. }
  105. fclose($fp);
  106. @chmod($file, 0777);
  107. @unlink($file);
  108. return true;
  109. } elseif (!is_file($file) or ($fp = @fopen($file, 'ab')) === false) {
  110. return false;
  111. }
  112. fclose($fp);
  113. return true;
  114. }
  115. }
  116. if (!function_exists('rmdirs')) {
  117. /**
  118. * 删除文件夹
  119. * @param string $dirname 目录
  120. * @param bool $withself 是否删除自身
  121. * @return boolean
  122. */
  123. function rmdirs($dirname, $withself = true)
  124. {
  125. if (!is_dir($dirname)) {
  126. return false;
  127. }
  128. $files = new RecursiveIteratorIterator(
  129. new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS),
  130. RecursiveIteratorIterator::CHILD_FIRST
  131. );
  132. foreach ($files as $fileinfo) {
  133. $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
  134. $todo($fileinfo->getRealPath());
  135. }
  136. if ($withself) {
  137. @rmdir($dirname);
  138. }
  139. return true;
  140. }
  141. }
  142. if (!function_exists('copydirs')) {
  143. /**
  144. * 复制文件夹
  145. * @param string $source 源文件夹
  146. * @param string $dest 目标文件夹
  147. */
  148. function copydirs($source, $dest)
  149. {
  150. if (!is_dir($dest)) {
  151. mkdir($dest, 0755, true);
  152. }
  153. foreach (
  154. $iterator = new RecursiveIteratorIterator(
  155. new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
  156. RecursiveIteratorIterator::SELF_FIRST
  157. ) as $item
  158. ) {
  159. if ($item->isDir()) {
  160. $sontDir = $dest . DS . $iterator->getSubPathName();
  161. if (!is_dir($sontDir)) {
  162. mkdir($sontDir, 0755, true);
  163. }
  164. } else {
  165. copy($item, $dest . DS . $iterator->getSubPathName());
  166. }
  167. }
  168. }
  169. }
  170. if (!function_exists('mb_ucfirst')) {
  171. function mb_ucfirst($string)
  172. {
  173. return mb_strtoupper(mb_substr($string, 0, 1)) . mb_strtolower(mb_substr($string, 1));
  174. }
  175. }
  176. if (!function_exists('addtion')) {
  177. /**
  178. * 附加关联字段数据
  179. * @param array $items 数据列表
  180. * @param mixed $fields 渲染的来源字段
  181. * @return array
  182. */
  183. function addtion($items, $fields)
  184. {
  185. if (!$items || !$fields) {
  186. return $items;
  187. }
  188. $fieldsArr = [];
  189. if (!is_array($fields)) {
  190. $arr = explode(',', $fields);
  191. foreach ($arr as $k => $v) {
  192. $fieldsArr[$v] = ['field' => $v];
  193. }
  194. } else {
  195. foreach ($fields as $k => $v) {
  196. if (is_array($v)) {
  197. $v['field'] = isset($v['field']) ? $v['field'] : $k;
  198. } else {
  199. $v = ['field' => $v];
  200. }
  201. $fieldsArr[$v['field']] = $v;
  202. }
  203. }
  204. foreach ($fieldsArr as $k => &$v) {
  205. $v = is_array($v) ? $v : ['field' => $v];
  206. $v['display'] = isset($v['display']) ? $v['display'] : str_replace(['_ids', '_id'], ['_names', '_name'], $v['field']);
  207. $v['primary'] = isset($v['primary']) ? $v['primary'] : '';
  208. $v['column'] = isset($v['column']) ? $v['column'] : 'name';
  209. $v['model'] = isset($v['model']) ? $v['model'] : '';
  210. $v['table'] = isset($v['table']) ? $v['table'] : '';
  211. $v['name'] = isset($v['name']) ? $v['name'] : str_replace(['_ids', '_id'], '', $v['field']);
  212. }
  213. unset($v);
  214. $ids = [];
  215. $fields = array_keys($fieldsArr);
  216. foreach ($items as $k => $v) {
  217. foreach ($fields as $m => $n) {
  218. if (isset($v[$n])) {
  219. $ids[$n] = array_merge(isset($ids[$n]) && is_array($ids[$n]) ? $ids[$n] : [], explode(',', $v[$n]));
  220. }
  221. }
  222. }
  223. $result = [];
  224. foreach ($fieldsArr as $k => $v) {
  225. if ($v['model']) {
  226. $model = new $v['model'];
  227. } else {
  228. $model = $v['name'] ? \think\Db::name($v['name']) : \think\Db::table($v['table']);
  229. }
  230. $primary = $v['primary'] ? $v['primary'] : $model->getPk();
  231. $result[$v['field']] = isset($ids[$v['field']]) ? $model->where($primary, 'in', $ids[$v['field']])->column("{$primary},{$v['column']}") : [];
  232. }
  233. foreach ($items as $k => &$v) {
  234. foreach ($fields as $m => $n) {
  235. if (isset($v[$n])) {
  236. $curr = array_flip(explode(',', $v[$n]));
  237. $v[$fieldsArr[$n]['display']] = implode(',', array_intersect_key($result[$n], $curr));
  238. }
  239. }
  240. }
  241. return $items;
  242. }
  243. }
  244. if (!function_exists('var_export_short')) {
  245. /**
  246. * 使用短标签打印或返回数组结构
  247. * @param mixed $data
  248. * @param boolean $return 是否返回数据
  249. * @return string
  250. */
  251. function var_export_short($data, $return = true)
  252. {
  253. return var_export($data, $return);
  254. $replaced = [];
  255. $count = 0;
  256. //判断是否是对象
  257. if (is_resource($data) || is_object($data)) {
  258. return var_export($data, $return);
  259. }
  260. //判断是否有特殊的键名
  261. $specialKey = false;
  262. array_walk_recursive($data, function (&$value, &$key) use (&$specialKey) {
  263. if (is_string($key) && (stripos($key, "\n") !== false || stripos($key, "array (") !== false)) {
  264. $specialKey = true;
  265. }
  266. });
  267. if ($specialKey) {
  268. return var_export($data, $return);
  269. }
  270. array_walk_recursive($data, function (&$value, &$key) use (&$replaced, &$count, &$stringcheck) {
  271. if (is_object($value) || is_resource($value)) {
  272. $replaced[$count] = var_export($value, true);
  273. $value = "##<{$count}>##";
  274. } else {
  275. if (is_string($value) && (stripos($value, "\n") !== false || stripos($value, "array (") !== false)) {
  276. $index = array_search($value, $replaced);
  277. if ($index === false) {
  278. $replaced[$count] = var_export($value, true);
  279. $value = "##<{$count}>##";
  280. } else {
  281. $value = "##<{$index}>##";
  282. }
  283. }
  284. }
  285. $count++;
  286. });
  287. $dump = var_export($data, true);
  288. $dump = preg_replace('#(?:\A|\n)([ ]*)array \(#i', '[', $dump); // Starts
  289. $dump = preg_replace('#\n([ ]*)\),#', "\n$1],", $dump); // Ends
  290. $dump = preg_replace('#=> \[\n\s+\],\n#', "=> [],\n", $dump); // Empties
  291. $dump = preg_replace('#\)$#', "]", $dump); //End
  292. if ($replaced) {
  293. $dump = preg_replace_callback("/'##<(\d+)>##'/", function ($matches) use ($replaced) {
  294. return isset($replaced[$matches[1]]) ? $replaced[$matches[1]] : "''";
  295. }, $dump);
  296. }
  297. if ($return === true) {
  298. return $dump;
  299. } else {
  300. echo $dump;
  301. }
  302. }
  303. }
  304. if (!function_exists('letter_avatar')) {
  305. /**
  306. * 首字母头像
  307. * @param $text
  308. * @return string
  309. */
  310. function letter_avatar($text)
  311. {
  312. $total = unpack('L', hash('adler32', $text, true))[1];
  313. $hue = $total % 360;
  314. list($r, $g, $b) = hsv2rgb($hue / 360, 0.3, 0.9);
  315. $bg = "rgb({$r},{$g},{$b})";
  316. $color = "#ffffff";
  317. $first = mb_strtoupper(mb_substr($text, 0, 1));
  318. $src = base64_encode('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="100" width="100"><rect fill="' . $bg . '" x="0" y="0" width="100" height="100"></rect><text x="50" y="50" font-size="50" text-copy="fast" fill="' . $color . '" text-anchor="middle" text-rights="admin" dominant-baseline="central">' . $first . '</text></svg>');
  319. $value = 'data:image/svg+xml;base64,' . $src;
  320. return $value;
  321. }
  322. }
  323. if (!function_exists('hsv2rgb')) {
  324. function hsv2rgb($h, $s, $v)
  325. {
  326. $r = $g = $b = 0;
  327. $i = floor($h * 6);
  328. $f = $h * 6 - $i;
  329. $p = $v * (1 - $s);
  330. $q = $v * (1 - $f * $s);
  331. $t = $v * (1 - (1 - $f) * $s);
  332. switch ($i % 6) {
  333. case 0:
  334. $r = $v;
  335. $g = $t;
  336. $b = $p;
  337. break;
  338. case 1:
  339. $r = $q;
  340. $g = $v;
  341. $b = $p;
  342. break;
  343. case 2:
  344. $r = $p;
  345. $g = $v;
  346. $b = $t;
  347. break;
  348. case 3:
  349. $r = $p;
  350. $g = $q;
  351. $b = $v;
  352. break;
  353. case 4:
  354. $r = $t;
  355. $g = $p;
  356. $b = $v;
  357. break;
  358. case 5:
  359. $r = $v;
  360. $g = $p;
  361. $b = $q;
  362. break;
  363. }
  364. return [
  365. floor($r * 255),
  366. floor($g * 255),
  367. floor($b * 255)
  368. ];
  369. }
  370. }
  371. if (!function_exists('check_nav_active')) {
  372. /**
  373. * 检测会员中心导航是否高亮
  374. */
  375. function check_nav_active($url, $classname = 'active')
  376. {
  377. $auth = \app\common\library\Auth::instance();
  378. $requestUrl = $auth->getRequestUri();
  379. $url = ltrim($url, '/');
  380. return $requestUrl === str_replace(".", "/", $url) ? $classname : '';
  381. }
  382. }
  383. if (!function_exists('check_cors_request')) {
  384. /**
  385. * 跨域检测
  386. */
  387. function check_cors_request()
  388. {
  389. if (isset($_SERVER['HTTP_ORIGIN']) && $_SERVER['HTTP_ORIGIN']) {
  390. $info = parse_url($_SERVER['HTTP_ORIGIN']);
  391. $domainArr = explode(',', config('fastadmin.cors_request_domain'));
  392. $domainArr[] = request()->host(true);
  393. if (in_array("*", $domainArr) || in_array($_SERVER['HTTP_ORIGIN'], $domainArr) || (isset($info['host']) && in_array($info['host'], $domainArr))) {
  394. header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
  395. } else {
  396. $response = Response::create('跨域检测无效', 'html', 403);
  397. throw new HttpResponseException($response);
  398. }
  399. header('Access-Control-Allow-Credentials: true');
  400. header('Access-Control-Max-Age: 86400');
  401. if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  402. if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) {
  403. header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
  404. }
  405. if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) {
  406. header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
  407. }
  408. $response = Response::create('', 'html');
  409. throw new HttpResponseException($response);
  410. }
  411. }
  412. }
  413. }
  414. if (!function_exists('xss_clean')) {
  415. /**
  416. * 清理XSS
  417. */
  418. function xss_clean($content, $is_image = false)
  419. {
  420. return \app\common\library\Security::instance()->xss_clean($content, $is_image);
  421. }
  422. }
  423. if (!function_exists('check_ip_allowed')) {
  424. /**
  425. * 检测IP是否允许
  426. * @param string $ip IP地址
  427. */
  428. function check_ip_allowed($ip = null)
  429. {
  430. $ip = is_null($ip) ? request()->ip() : $ip;
  431. $forbiddenipArr = config('site.forbiddenip');
  432. $forbiddenipArr = !$forbiddenipArr ? [] : $forbiddenipArr;
  433. $forbiddenipArr = is_array($forbiddenipArr) ? $forbiddenipArr : array_filter(explode("\n", str_replace("\r\n", "\n", $forbiddenipArr)));
  434. if ($forbiddenipArr && \Symfony\Component\HttpFoundation\IpUtils::checkIp($ip, $forbiddenipArr)) {
  435. $response = Response::create('请求无权访问', 'html', 403);
  436. throw new HttpResponseException($response);
  437. }
  438. }
  439. }
  440. //结果集信息里,生日转换年龄
  441. function list_birthday_age($list){
  442. if(!$list || empty($list)){
  443. return $list;
  444. }
  445. foreach($list as $vo => $info){
  446. $list[$vo]['age'] = birthtime_to_age($info['birthday']);
  447. }
  448. return $list;
  449. }
  450. //结果集信息里,多个字段需要增加domain_cdnurl
  451. function list_domain_image($list,$field){
  452. if(!$list || empty($list)){
  453. return $list;
  454. }
  455. foreach($list as $vo => $info){
  456. $list[$vo] = info_domain_image($info,$field);
  457. }
  458. return $list;
  459. }
  460. //单条信息里,多个字段需要增加domain_cdnurl
  461. //支持image,images
  462. function info_domain_image($data,$field){
  463. if(!$data || empty($data)){
  464. return $data;
  465. }
  466. foreach($data as $key => $val){
  467. if(in_array($key,$field)){
  468. $data[$key] = one_domain_image($val);
  469. }
  470. }
  471. return $data;
  472. }
  473. //支持单个字段,需要增加domain_cdnurl
  474. //支持image,images
  475. function one_domain_image($one){
  476. if(!$one){
  477. return $one;
  478. }
  479. if(strpos($one,',')){
  480. //逗号隔开的多个图片
  481. $one = explode(',',$one);
  482. foreach($one as $k => $v){
  483. $one[$k] = localpath_to_netpath($v);
  484. }
  485. $one = implode(',',$one);
  486. }else{
  487. $one = localpath_to_netpath($one);
  488. }
  489. return $one;
  490. }
  491. //本地地址转换为网络地址
  492. function localpath_to_netpath($path)
  493. {
  494. if (empty($path)) {
  495. return '';
  496. } elseif (strrpos($path, 'http') !== false) {
  497. return $path;
  498. } else {
  499. return config('upload.cdnurl') . str_replace("\\", "/", $path);
  500. }
  501. }
  502. //秒 转换 日月分
  503. function Sec2Time($time){
  504. if(is_numeric($time)){
  505. $value = array(
  506. 'years' => 0, 'days' => 0, 'hours' => 0,
  507. 'minutes' => 0, 'seconds' => 0,
  508. );
  509. /*if($time >= 31556926){
  510. $value['years'] = floor($time/31556926);
  511. $time = ($time%31556926);
  512. }*/
  513. if($time >= 86400){
  514. $value['days'] = floor($time/86400);
  515. $time = ($time%86400);
  516. }
  517. if($time >= 3600){
  518. $value['hours'] = floor($time/3600);
  519. $time = ($time%3600);
  520. }
  521. if($time >= 60){
  522. $value['minutes'] = floor($time/60);
  523. $time = ($time%60);
  524. }
  525. $value['seconds'] = floor($time);
  526. //return (array) $value;
  527. //$t=$value['years'] .'年'. $value['days'] .'天'.' '. $value['hours'] .'小时'. $value['minutes'] .'分'.$value['seconds'].'秒';
  528. $t = $value['days'] .'天' . $value['hours'] .'小时'. $value['minutes'] .'分';
  529. return $t;
  530. }else{
  531. return '0天';
  532. }
  533. }
  534. //生日转年龄
  535. function birthtime_to_age($birthtime){
  536. // $birthtime = strtotime('1990-11-06');
  537. if(!$birthtime){
  538. return 0;
  539. }
  540. list($y1,$m1,$d1) = explode("-",date("Y-m-d",$birthtime));
  541. list($y2,$m2,$d2) = explode("-",date("Y-m-d",time()));
  542. $age = $y2 - $y1;
  543. if((int)($m2.$d2) < (int)($m1.$d1))
  544. {$age -= 1;}
  545. if($age < 0){
  546. $age = 0;
  547. }
  548. return $age;
  549. }
  550. if(!function_exists('mk_dir')) {
  551. /**
  552. * 新建目录
  553. */
  554. function mk_dir($dir, $mode = 0770, $tmp = true)
  555. {
  556. $mode = 0770;
  557. if(is_file($dir)) {
  558. //有同名文件
  559. return false;
  560. } else {
  561. if(!is_dir($dir)) { //目录不存在
  562. $dir_up = dirname($dir); //上级目录
  563. if(!is_dir($dir_up)) {
  564. //上级不存在
  565. $rs = @mk_dir($dir_up);
  566. if(!$rs) return false;
  567. }
  568. $rs = @mkdir($dir, $mode); //新建
  569. if(!$rs) return false;
  570. $rs = @chmod($dir, $mode); //改权限
  571. if(!$rs) return false;
  572. }
  573. return true;
  574. }
  575. }
  576. }
  577. /**
  578. * 在线支付日志
  579. */
  580. function filePut($info,$text='notify.txt'){
  581. if(is_array($info)) {
  582. $info = json_encode($info, JSON_UNESCAPED_UNICODE);
  583. }
  584. if(!file_exist(RUNTIME_PATH.'paylog/')) {
  585. mk_dir(RUNTIME_PATH.'paylog/');
  586. }
  587. $file = RUNTIME_PATH.'paylog/'.$text;
  588. touch_file($file);
  589. file_put_contents($file, "\r\n".date('Y-m-d H:i:s').' '.$info, FILE_APPEND);
  590. }
  591. if(!function_exists('touch_file')) {
  592. /**
  593. * 新建文件
  594. */
  595. function touch_file($file = '')
  596. {
  597. if($file) {
  598. if(!file_exists($file)) {
  599. @touch($file);
  600. @chmod($file, 0770);
  601. }
  602. }
  603. }
  604. }
  605. if(!function_exists('file_exist')) {
  606. /**
  607. * 检测文件是否存在
  608. * @param $file
  609. * @return string
  610. */
  611. function file_exist($file)
  612. {
  613. if(false === strpos($file, 'http')) { //本地文件
  614. if(0 === strpos($file, '/upload')) {
  615. $file = '.'.$file;
  616. }
  617. return file_exists($file);
  618. } else { //网络文件
  619. $ch = curl_init();
  620. curl_setopt($ch, CURLOPT_URL, $file);
  621. curl_setopt($ch, CURLOPT_TIMEOUT, 2);
  622. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  623. curl_exec($ch);
  624. $status = curl_getinfo($ch,CURLINFO_HTTP_CODE);
  625. curl_close($ch);
  626. if(in_array(substr($status, 0, 1), [2, 3])) {
  627. return true;
  628. } else {
  629. return false;
  630. }
  631. }
  632. }
  633. }
  634. /**
  635. * 发起HTTPS请求
  636. */
  637. function curl_post($url, $data, $header = '', $timeOut = 0)
  638. {
  639. //初始化curl
  640. $ch = curl_init();
  641. //参数设置
  642. curl_setopt($ch, CURLOPT_URL, $url);
  643. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  644. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  645. curl_setopt($ch, CURLOPT_TIMEOUT, $timeOut);
  646. curl_setopt($ch, CURLOPT_HEADER, 0);
  647. curl_setopt($ch, CURLOPT_POST, 1);
  648. curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  649. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  650. if($header != '') {
  651. curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
  652. }
  653. $result = curl_exec($ch);
  654. //连接失败
  655. if($result == FALSE) {
  656. //\think\Log::record('[ CURL ] ERROR ' . curl_error($ch)."\n".var_export(debug_backtrace(), true)."\n", 'error');
  657. }
  658. curl_close($ch);
  659. return $result;
  660. }
  661. /**
  662. * 发起HTTP GET请求
  663. */
  664. function curl_get($url)
  665. {
  666. $oCurl = curl_init();
  667. if(stripos($url, "https://") !== FALSE) {
  668. curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
  669. curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
  670. curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
  671. }
  672. curl_setopt($oCurl, CURLOPT_TIMEOUT, 3);
  673. curl_setopt($oCurl, CURLOPT_URL, $url);
  674. curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
  675. $sContent = curl_exec($oCurl);
  676. $aStatus = curl_getinfo($oCurl);
  677. $error = curl_error($oCurl);
  678. curl_close($oCurl);
  679. if($error) {
  680. $sContent = file_get_contents($url);
  681. return $sContent;
  682. }
  683. if(intval($aStatus["http_code"]) == 200) {
  684. return $sContent;
  685. } else {
  686. return false;
  687. }
  688. }
  689. //创建订单号
  690. function createUniqueNo($prifix = 'P',$id = 0)
  691. {
  692. $s = 0;
  693. $ms = 0;
  694. list($ms, $s) = explode(' ', microtime());
  695. $ms = substr($ms, 2, 6); //获取微妙
  696. $rt = $prifix.date('ymdHis', $s).$ms.$id; //年月日时分秒.用户id对10取余.微秒
  697. return $rt;
  698. }
  699. //时间转换
  700. function get_last_time($time = NULL) {
  701. $text = '';
  702. $time = $time === NULL || $time > time() ? time() : intval($time);
  703. $t = time() - $time; //时间差 (秒)
  704. $y = date('Y', $time)-date('Y', time());//是否跨年
  705. switch($t){
  706. case $t == 0:
  707. $text = '刚刚';
  708. break;
  709. case $t < 60:
  710. $text = $t . '秒前'; // 一分钟内
  711. break;
  712. case $t < 60 * 60:
  713. $text = floor($t / 60) . '分钟前'; //一小时内
  714. break;
  715. case $t < 60 * 60 * 24:
  716. $text = floor($t / (60 * 60)) . '小时前'; // 一天内
  717. break;
  718. case $t < 60 * 60 * 24 * 3:
  719. $text = floor($time/(60*60*24)) ==1 ?'昨天 ' . date('H:i', $time) : '前天 ' . date('H:i', $time) ; //昨天和前天
  720. break;
  721. case $t < 60 * 60 * 24 * 30:
  722. $text = date('m月d日 H:i', $time); //一个月内
  723. break;
  724. case $t < 60 * 60 * 24 * 365&&$y==0:
  725. $text = date('m月d日', $time); //一年内
  726. break;
  727. default:
  728. $text = date('Y年m月d日', $time); //一年以前
  729. break;
  730. }
  731. return $text;
  732. }
  733. //增加亲密度
  734. function addintimacy($uid = 0, $other_uid = 0, $value = 0) {
  735. //增加亲密度
  736. $level_remark = ''; //亲密度等级是否变动: 0未变动 >0是亲密度等级
  737. $user_intimacy_info = Db::name('user_intimacy')->where(['uid' => $uid, 'other_uid' => $other_uid])->find();
  738. if ($user_intimacy_info) {
  739. $user_intimacy_data['value'] = $user_intimacy_info['value'] + $value;
  740. $user_intimacy_data['updatetime'] = time();
  741. $level = Db::name('intimacy_level')->where(['value' => ['elt', $user_intimacy_data['value']]])->order('id desc')->find();
  742. if ($level) {
  743. $user_intimacy_data['level'] = $level['level'];
  744. if ($level['level'] != $user_intimacy_info['level']) {
  745. $level_remark = "恭喜你们亲密度达到".$level['level']."级,获得称号'".$level['name']."'";
  746. }
  747. }
  748. $user_intimacy_rs = Db::name('user_intimacy')->where(['uid' => $uid, 'other_uid' => $other_uid])->setField($user_intimacy_data);
  749. } else {
  750. $user_intimacy_data['uid'] = $uid;
  751. $user_intimacy_data['other_uid'] = $other_uid;
  752. $user_intimacy_data['value'] = $value;
  753. $user_intimacy_data['createtime'] = time();
  754. $user_intimacy_data['updatetime'] = time();
  755. $level = Db::name('intimacy_level')->where(['value' => ['elt', $value]])->order('id desc')->find();
  756. if ($level) {
  757. $user_intimacy_data['level'] = $level['level'];
  758. $level_remark = "恭喜你们亲密度达到".$level['level']."级,获得称号'".$level['name']."'";
  759. }
  760. $user_intimacy_rs = Db::name('user_intimacy')->insertGetId($user_intimacy_data);
  761. }
  762. return ['status' => $user_intimacy_rs, 'level_remark' => $level_remark];
  763. }
  764. /**
  765. * [getMillisecond 获取毫秒级时间戳]
  766. * @return [type] [description]
  767. */
  768. function getMillisecond() {
  769. list($t1, $t2) = explode(' ', microtime());
  770. return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
  771. }
  772. function p($arr) {
  773. header('content-type:text/html;charset=utf-8');
  774. echo '<pre>';
  775. print_r($arr);
  776. echo '</pre>';
  777. }
  778. //获取支付宝用户信息
  779. function getAlipayInfo($auth_code = '') {
  780. if (!$auth_code) {
  781. return ['status' => 0, 'info' => '授权码缺失'];
  782. }
  783. $aliPayPath = '../extend/AliPay/aop/';
  784. require_once $aliPayPath . 'AopClient.php';
  785. require_once $aliPayPath . 'AopCertClient.php';
  786. require_once $aliPayPath . 'AopCertification.php';
  787. require_once $aliPayPath . 'AlipayConfig.php';
  788. require_once $aliPayPath . 'request/AlipaySystemOauthTokenRequest.php';
  789. require_once $aliPayPath . 'request/AlipayUserInfoShareRequest.php';
  790. $privateKey = config('private_key');//"<-- 请填写您的应用私钥,例如:MIIEvQIBADANB ... ... -->";
  791. $alipayConfig = new AlipayConfig();
  792. $alipayConfig->setPrivateKey($privateKey);
  793. $alipayConfig->setServerUrl("https://openapi.alipay.com/gateway.do");
  794. $alipayConfig->setAppId(config('ali_app_id')); //"<-- 请填写您的AppId,例如:2019091767145019 -->"
  795. $alipayConfig->setCharset("UTF-8");
  796. $alipayConfig->setSignType("RSA2");
  797. $alipayConfig->setEncryptKey("");
  798. $alipayConfig->setFormat("json");
  799. $alipayConfig->setAppCertPath('../extend/AliPay/cert/appCertPublicKey_2021003139615320.crt');//"<-- 请填写您的应用公钥证书文件路径,例如:/foo/appCertPublicKey_2019051064521003.crt -->"
  800. $alipayConfig->setAlipayPublicCertPath('../extend/AliPay/cert/alipayCertPublicKey_RSA2.crt');//"<-- 请填写您的支付宝公钥证书文件路径,例如:/foo/alipayCertPublicKey_RSA2.crt -->"
  801. $alipayConfig->setRootCertPath('../extend/AliPay/cert/alipayRootCert.crt');//"<-- 请填写您的支付宝根证书文件路径,例如:/foo/alipayRootCert.crt -->"
  802. $alipayClient = new AopCertClient($alipayConfig);
  803. $alipayClient->isCheckAlipayPublicCert = true;
  804. $request = new AlipaySystemOauthTokenRequest();
  805. $request->setGrantType("authorization_code");
  806. $request->setCode($auth_code);//设置授权码
  807. $result = $alipayClient->execute($request);
  808. $result = json_decode(json_encode($result), true);
  809. /*$aliPayPath = '../extend/AliPay/alipay-sdk/';
  810. require_once($aliPayPath . "aop/AopClient.php");
  811. require_once($aliPayPath . "aop/SignData.php");
  812. require_once($aliPayPath . 'aop/request/AlipaySystemOauthTokenRequest.php');
  813. require_once($aliPayPath . 'aop/request/AlipayUserInfoShareRequest.php');
  814. $aop = new \AopClient ();
  815. $aop->appId = config('ali_app_id');
  816. $aop->rsaPrivateKey = config('private_key');
  817. $aop->alipayrsaPublicKey = config('ali_public_key');
  818. $aop->signType = 'RSA2';
  819. $request = new \AlipaySystemOauthTokenRequest ();
  820. $request->setGrantType("authorization_code");
  821. $request->setCode($auth_code);//设置授权码
  822. // $request->setRefreshToken("201208134b203fe6c11548bcabd8da5bb087a83b"); //刷刷新令牌,上次换取访问令牌时得到
  823. $result = $aop->execute ($request);
  824. $result = json_decode(json_encode($result), true);*/
  825. if (!isset($result['alipay_system_oauth_token_response'])) {
  826. return ['status' => 0, 'info' => '获取用户授权失败'];
  827. }
  828. //用户访问令牌
  829. $access_token = $result['alipay_system_oauth_token_response']['access_token'];
  830. if (empty($access_token)) {
  831. return ['status' => 0, 'info' => '获取用户授权失败'];
  832. }
  833. //获取用户信息
  834. $request_two = new \AlipayUserInfoShareRequest ();
  835. $rs = $alipayClient->execute ($request_two , $access_token );
  836. $rs = json_decode(json_encode($rs), true);
  837. /*
  838. * Array(
  839. [alipay_user_info_share_response] => Array
  840. (
  841. [code] => 10000
  842. [msg] => Success
  843. [avatar] => https://tfs.alipayobjects.com/images/partner/T1BQJsXhhbXXXXXXXX 头像
  844. [city] => 临沂市 市名称。
  845. [gender] => m 【注意】只有is_certified为T的时候才有意义,否则不保证准确性. 性别(F:女性;M:男性)。
  846. [is_certified] => T 是否通过实名认证。T是通过 F是没有实名认证。
  847. [is_student_certified] => F 是否是学生 T是 F否
  848. [nick_name] => 风的追求 用户昵称
  849. [province] => 山东省 省份名称
  850. [user_id] => 2088902918001020 支付宝用户的userId
  851. [user_status] => T 用户状态(Q/T/B/W)。 Q代表快速注册用户 T代表已认证用户 B代表被冻结账户 W代表已注册,未激活的账户
  852. [user_type] => 2 用户类型(1/2) 1代表公司账户2代表个人账户
  853. )
  854. )
  855. */
  856. return ['status' => 1, 'info' => '支付宝用户信息', 'data' => $rs['alipay_user_info_share_response']];
  857. }
  858. if (!function_exists('day_now')) {
  859. //返回今天的开始时间和结束时间
  860. function day_now()
  861. {
  862. $arr = [
  863. mktime(0, 0, 0, date('m'), date('d'), date('Y')),
  864. mktime(23, 59, 59, date('m'), date('d'), date('Y')),
  865. ];
  866. return $arr;
  867. }
  868. }
  869. if (!function_exists('day_yesterday')) {
  870. //返回昨天开始结束时间 改造上边的方法
  871. function day_yesterday()
  872. {
  873. $yesterday = date('d') - 1;
  874. $arr = [
  875. mktime(0, 0, 0, date('m'), $yesterday, date('Y')),
  876. mktime(23, 59, 59, date('m'), $yesterday, date('Y')),
  877. ];
  878. return $arr;
  879. }
  880. }
  881. if (!function_exists('week_now')) {
  882. //获取当前时间的本周开始结束时间
  883. function week_now()
  884. {
  885. $arr = [
  886. mktime(0, 0 , 0,date("m"),date("d")-date("N")+1,date("Y")),
  887. mktime(23,59,59,date("m"),date("d")-date("N")+7,date("Y")),
  888. ];
  889. return $arr;
  890. }
  891. }
  892. if (!function_exists('last_week')) {
  893. //返回上周开始和结束的时间戳
  894. function last_week()
  895. {
  896. $arr = [
  897. strtotime('last week Monday', time()),
  898. strtotime('last week Sunday +1 days -1 seconds', time())
  899. ];
  900. return $arr;
  901. }
  902. }
  903. if (!function_exists('now_month')) {
  904. //返回上周开始和结束的时间戳
  905. function now_month()
  906. {
  907. $arr = [
  908. //strtotime('-30 day', time()),
  909. mktime(0, 0 , 0,date("m"),date("d")-30,date("Y")),
  910. mktime(23, 59 , 59,date("m"),date("d"),date("Y")),
  911. ];
  912. return $arr;
  913. }
  914. }
  915. if (!function_exists('dd')) {
  916. function dd(...$vars){
  917. foreach ($vars as $v) {
  918. dump($v);
  919. }
  920. exit();
  921. }
  922. }