心理咨询网
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
  1. <?php
  2. /**
  3. * @copyright (C)2016-2099 Hnaoyun Inc.
  4. * @author XingMeng
  5. * @email hnxsh@foxmail.com
  6. * @date 2017年11月5日
  7. *
  8. */
  9. use core\basic\Config;
  10. // 获取用户浏览器类型
  11. function get_user_bs($bs = null)
  12. {
  13. if (isset($_SERVER["HTTP_USER_AGENT"])) {
  14. $user_agent = strtolower($_SERVER["HTTP_USER_AGENT"]);
  15. } else {
  16. return null;
  17. }
  18. // 直接检测传递的值
  19. if ($bs) {
  20. if (strpos($user_agent, strtolower($bs))) {
  21. return true;
  22. } else {
  23. return false;
  24. }
  25. }
  26. // 固定检测
  27. if (strpos($user_agent, 'micromessenger')) {
  28. $user_bs = 'Weixin';
  29. } elseif (strpos($user_agent, 'qq')) {
  30. $user_bs = 'QQ';
  31. } elseif (strpos($user_agent, 'weibo')) {
  32. $user_bs = 'Weibo';
  33. } elseif (strpos($user_agent, 'alipayclient')) {
  34. $user_bs = 'Alipay';
  35. } elseif (strpos($user_agent, 'trident/7.0')) {
  36. $user_bs = 'IE11'; // 新版本IE优先,避免360等浏览器的兼容模式检测错误
  37. } elseif (strpos($user_agent, 'trident/6.0')) {
  38. $user_bs = 'IE10';
  39. } elseif (strpos($user_agent, 'trident/5.0')) {
  40. $user_bs = 'IE9';
  41. } elseif (strpos($user_agent, 'trident/4.0')) {
  42. $user_bs = 'IE8';
  43. } elseif (strpos($user_agent, 'msie 7.0')) {
  44. $user_bs = 'IE7';
  45. } elseif (strpos($user_agent, 'msie 6.0')) {
  46. $user_bs = 'IE6';
  47. } elseif (strpos($user_agent, 'edge')) {
  48. $user_bs = 'Edge';
  49. } elseif (strpos($user_agent, 'firefox')) {
  50. $user_bs = 'Firefox';
  51. } elseif (strpos($user_agent, 'chrome') || strpos($user_agent, 'android')) {
  52. $user_bs = 'Chrome';
  53. } elseif (strpos($user_agent, 'safari')) {
  54. $user_bs = 'Safari';
  55. } elseif (strpos($user_agent, 'mj12bot')) {
  56. $user_bs = 'MJ12bot';
  57. } else {
  58. $user_bs = 'Other';
  59. }
  60. return $user_bs;
  61. }
  62. // 获取用户操作系统类型
  63. function get_user_os($osstr = null)
  64. {
  65. if (isset($_SERVER["HTTP_USER_AGENT"])) {
  66. $user_agent = strtolower($_SERVER["HTTP_USER_AGENT"]);
  67. } else {
  68. return null;
  69. }
  70. // 直接检测传递的值
  71. if ($osstr) {
  72. if (strpos($user_agent, strtolower($osstr))) {
  73. return true;
  74. } else {
  75. return false;
  76. }
  77. }
  78. if (strpos($user_agent, 'windows nt 5.0')) {
  79. $user_os = 'Windows 2000';
  80. } elseif (strpos($user_agent, 'windows nt 9')) {
  81. $user_os = 'Windows 9X';
  82. } elseif (strpos($user_agent, 'windows nt 5.1')) {
  83. $user_os = 'Windows XP';
  84. } elseif (strpos($user_agent, 'windows nt 5.2')) {
  85. $user_os = 'Windows 2003';
  86. } elseif (strpos($user_agent, 'windows nt 6.0')) {
  87. $user_os = 'Windows Vista';
  88. } elseif (strpos($user_agent, 'windows nt 6.1')) {
  89. $user_os = 'Windows 7';
  90. } elseif (strpos($user_agent, 'windows nt 6.2')) {
  91. $user_os = 'Windows 8';
  92. } elseif (strpos($user_agent, 'windows nt 6.3')) {
  93. $user_os = 'Windows 8.1';
  94. } elseif (strpos($user_agent, 'windows nt 10')) {
  95. $user_os = 'Windows 10';
  96. } elseif (strpos($user_agent, 'windows phone')) {
  97. $user_os = 'Windows Phone';
  98. } elseif (strpos($user_agent, 'android')) {
  99. $user_os = 'Android';
  100. } elseif (strpos($user_agent, 'iphone')) {
  101. $user_os = 'iPhone';
  102. } elseif (strpos($user_agent, 'ipad')) {
  103. $user_os = 'iPad';
  104. } elseif (strpos($user_agent, 'mac')) {
  105. $user_os = 'Mac';
  106. } elseif (strpos($user_agent, 'sunos')) {
  107. $user_os = 'Sun OS';
  108. } elseif (strpos($user_agent, 'bsd')) {
  109. $user_os = 'BSD';
  110. } elseif (strpos($user_agent, 'ubuntu')) {
  111. $user_os = 'Ubuntu';
  112. } elseif (strpos($user_agent, 'linux')) {
  113. $user_os = 'Linux';
  114. } elseif (strpos($user_agent, 'unix')) {
  115. $user_os = 'Unix';
  116. } else {
  117. $user_os = 'Other';
  118. }
  119. return $user_os;
  120. }
  121. // 获取用户IP
  122. function get_user_ip(): string
  123. {
  124. if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  125. $cip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  126. } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
  127. $cip = $_SERVER['HTTP_CLIENT_IP'];
  128. } else {
  129. $cip = $_SERVER['REMOTE_ADDR'];
  130. }
  131. if ($cip == '::1') { // 使用localhost时
  132. $cip = '127.0.0.1';
  133. }
  134. if (! preg_match('/^[0-9\.]+$/', $cip)) { // 非标准的IP
  135. $cip = '0.0.0.0';
  136. }
  137. return htmlspecialchars($cip);
  138. }
  139. // 执行URL请求,并返回数据
  140. function get_url($url, $fields = array(), $UserAgent = null, $vfSSL = false)
  141. {
  142. $SSL = substr($url, 0, 8) == "https://" ? true : false;
  143. $ch = curl_init();
  144. if ($UserAgent) { // 在HTTP请求中包含一个"User-Agent: "头的字符串。
  145. curl_setopt($ch, CURLOPT_USERAGENT, $UserAgent);
  146. } else {
  147. curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER["HTTP_USER_AGENT"]);
  148. }
  149. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); // 在发起连接前等待的时间,如果设置为0,则无限等待
  150. curl_setopt($ch, CURLOPT_TIMEOUT, 90); // 设置cURL允许执行的最长秒数
  151. curl_setopt($ch, CURLOPT_URL, $url); // 设置请求地址
  152. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 设置cURL 参数,要求结果保存到字符串中还是输出到屏幕上。
  153. // SSL验证
  154. if ($SSL) {
  155. if ($vfSSL) {
  156. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
  157. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
  158. curl_setopt($ch, CURLOPT_CAINFO, CORE_PATH . '/cacert.pem');
  159. } else {
  160. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
  161. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 不检查证书中是否设置域名
  162. }
  163. }
  164. // 数据字段
  165. if ($fields) {
  166. curl_setopt($ch, CURLOPT_POST, true);
  167. curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
  168. }
  169. $output = curl_exec($ch);
  170. if (curl_errno($ch)) {
  171. error('请求远程地址错误:' . curl_error($ch));
  172. }
  173. curl_close($ch);
  174. return $output;
  175. }
  176. // 返回时间戳格式化日期时间,默认当前
  177. function get_datetime($timestamp = null)
  178. {
  179. if (! $timestamp)
  180. $timestamp = time();
  181. return date('Y-m-d H:i:s', $timestamp);
  182. }
  183. // 返回时间戳格式化日期,默认当前
  184. function get_date($timestamp = null)
  185. {
  186. if (! $timestamp)
  187. $timestamp = time();
  188. return date('Y-m-d', $timestamp);
  189. }
  190. // 返回时间戳差值部分,年、月、日
  191. function get_date_diff($startstamp, $endstamp, $return = 'm')
  192. {
  193. $y = date('Y', $endstamp) - date('Y', $startstamp);
  194. $m = date('m', $endstamp) - date('m', $startstamp);
  195. switch ($return) {
  196. case 'y':
  197. if ($y <= 1) {
  198. $y = $m / 12;
  199. }
  200. $string = $y;
  201. break;
  202. case 'm':
  203. $string = $y * 12 + $m;
  204. break;
  205. case 'd':
  206. $string = ($endstamp - $startstamp) / 86400;
  207. break;
  208. }
  209. return $string;
  210. }
  211. // 生成无限极树,$data为二维数组数据
  212. function get_tree($data, $tid, $idField, $pidField, $sonName = 'son')
  213. {
  214. $tree = array();
  215. foreach ($data as $key => $value) {
  216. if (is_array($value)) {
  217. if ($value[$pidField] == "$tid") { // 父亲找到儿子
  218. $value[$sonName] = get_tree($data, $value[$idField], $idField, $pidField, $sonName);
  219. $tree[] = $value;
  220. }
  221. } else {
  222. if ($value->$pidField == "$tid") { // 父亲找到儿子
  223. $temp = clone $value;
  224. $temp->$sonName = get_tree($data, $value->$idField, $idField, $pidField, $sonName);
  225. $tree[] = $temp;
  226. }
  227. }
  228. }
  229. return $tree;
  230. }
  231. // 获取数据数组的映射数组
  232. function get_mapping($array, $vValue, $vKey = null)
  233. {
  234. if (! $array)
  235. return array();
  236. foreach ($array as $key => $value) {
  237. if (is_array($value)) {
  238. if ($vKey) {
  239. $result[$value[$vKey]] = $value[$vValue];
  240. } else {
  241. $result[] = $value[$vValue];
  242. }
  243. } elseif (is_object($value)) {
  244. if ($vKey) {
  245. $result[$value->$vKey] = $value->$vValue;
  246. } else {
  247. $result[] = $value->$vValue;
  248. }
  249. } else {
  250. return $array;
  251. }
  252. }
  253. return $result;
  254. }
  255. // 页码赋值,异常返回1
  256. function get_page()
  257. {
  258. if (isset($_GET['page'])) {
  259. $value = trim($_GET['page']);
  260. if (preg_match('/^[0-9]+$/', $value)) {
  261. return $value;
  262. }
  263. }
  264. return 1;
  265. }
  266. // 返回请求类型
  267. function get_request_method()
  268. {
  269. return $_SERVER['REQUEST_METHOD'];
  270. }
  271. // 获取当前完整URL地址
  272. function get_current_url()
  273. {
  274. $http_type = is_https() ? 'https://' : 'http://';
  275. return $http_type . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
  276. }
  277. // 获取字符串第N次出现位置
  278. function get_strpos($string, $find, $n)
  279. {
  280. $pos = strpos($string, $find);
  281. for ($i = 2; $i <= $n; $i ++) {
  282. $pos = strpos($string, $find, $pos + 1);
  283. }
  284. return $pos;
  285. }
  286. // array_column向下兼容低版本PHP
  287. if (! function_exists('array_column')) {
  288. function array_column($input, $columnKey, $indexKey = null)
  289. {
  290. $columnKeyIsNumber = (is_numeric($columnKey)) ? true : false;
  291. $indexKeyIsNull = (is_null($indexKey)) ? true : false;
  292. $indexKeyIsNumber = (is_numeric($indexKey)) ? true : false;
  293. $result = array();
  294. foreach ((array) $input as $key => $row) {
  295. if ($columnKeyIsNumber) {
  296. $tmp = array_slice($row, $columnKey, 1);
  297. $tmp = (is_array($tmp) && ! empty($tmp)) ? current($tmp) : null;
  298. } else {
  299. $tmp = isset($row[$columnKey]) ? $row[$columnKey] : null;
  300. }
  301. if (! $indexKeyIsNull) {
  302. if ($indexKeyIsNumber) {
  303. $key = array_slice($row, $indexKey, 1);
  304. $key = (is_array($key) && ! empty($key)) ? current($key) : null;
  305. $key = is_null($key) ? 0 : $key;
  306. } else {
  307. $key = isset($row[$indexKey]) ? $row[$indexKey] : 0;
  308. }
  309. }
  310. $result[$key] = $tmp;
  311. }
  312. return $result;
  313. }
  314. }
  315. /**
  316. * 系统信息弹出解析函数
  317. *
  318. * @param string $info_tpl模板
  319. * @param string $string内容
  320. * @param string $jump_url跳转地址
  321. * @param number $time时间
  322. */
  323. function parse_info_tpl($info_tpl, $string, $jump_url = null, $time = 0)
  324. {
  325. if (file_exists($info_tpl)) {
  326. $tpl_content = file_get_contents($info_tpl);
  327. if ($jump_url) {
  328. $timeout_js = "<script>var timeout = {time};var showbox = document.getElementById('time');show();function show(){showbox.innerHTML = timeout+ ' 秒后自动跳转';timeout--;if (timeout == 0) {window.location.href = '{url}';}else {setTimeout(function(){show();}, 1000);}}</script>";
  329. } else {
  330. $timeout_js = '';
  331. }
  332. $tpl_content = str_replace('{js}', $timeout_js, $tpl_content);
  333. $tpl_content = str_replace('{info}', $string, $tpl_content);
  334. $tpl_content = str_replace('{url}', $jump_url, $tpl_content);
  335. $tpl_content = str_replace('{time}', $time, $tpl_content);
  336. $tpl_content = str_replace('{sitedir}', SITE_DIR, $tpl_content);
  337. $tpl_content = str_replace('{coredir}', CORE_DIR, $tpl_content);
  338. $tpl_content = str_replace('{appversion}', APP_VERSION . '-' . RELEASE_TIME, $tpl_content);
  339. $tpl_content = str_replace('{serveros}', PHP_OS, $tpl_content);
  340. $tpl_content = str_replace('{serversoft}', $_SERVER['SERVER_SOFTWARE'], $tpl_content);
  341. return $tpl_content;
  342. } else {
  343. exit('<div style="font-size:50px;">:(</div>提示信息的模板文件不存在!');
  344. }
  345. }
  346. // 获取转义数据,支持字符串、数组、对象
  347. function escape_string($string)
  348. {
  349. if (! $string)
  350. return $string;
  351. if (is_array($string)) { // 数组处理
  352. foreach ($string as $key => $value) {
  353. $string[$key] = escape_string($value);
  354. }
  355. } elseif (is_object($string)) { // 对象处理
  356. foreach ($string as $key => $value) {
  357. $string->$key = escape_string($value);
  358. }
  359. } else { // 字符串处理
  360. $string = htmlspecialchars(trim($string), ENT_QUOTES, 'UTF-8');
  361. $string = addslashes($string);
  362. }
  363. return $string;
  364. }
  365. // 字符反转义html实体及斜杠,支持字符串、数组、对象
  366. function decode_string($string)
  367. {
  368. if (! $string)
  369. return $string;
  370. if (is_array($string)) { // 数组处理
  371. foreach ($string as $key => $value) {
  372. $string[$key] = decode_string($value);
  373. }
  374. } elseif (is_object($string)) { // 对象处理
  375. foreach ($string as $key => $value) {
  376. $string->$key = decode_string($value);
  377. }
  378. } else { // 字符串处理
  379. $string = stripcslashes($string);
  380. $string = htmlspecialchars_decode($string, ENT_QUOTES);
  381. $string = preg_replace_r('/pboot:if/i', 'pboot@if', $string); // 避免解码绕过问题
  382. }
  383. return $string;
  384. }
  385. // 字符反转义斜杠,支持字符串、数组、对象
  386. function decode_slashes($string)
  387. {
  388. if (! $string)
  389. return $string;
  390. if (is_array($string)) { // 数组处理
  391. foreach ($string as $key => $value) {
  392. $string[$key] = decode_slashes($value);
  393. }
  394. } elseif (is_object($string)) { // 对象处理
  395. foreach ($string as $key => $value) {
  396. $string->$key = decode_slashes($value);
  397. }
  398. } else { // 字符串处理
  399. $string = stripcslashes($string);
  400. }
  401. return $string;
  402. }
  403. // 字符串双层MD5加密
  404. function encrypt_string($string)
  405. {
  406. return md5(md5($string));
  407. }
  408. // 生成唯一标识符
  409. function get_uniqid()
  410. {
  411. return encrypt_string(uniqid(mt_rand(), true));
  412. }
  413. // 清洗html代码的空白符号
  414. function clear_html_blank($string)
  415. {
  416. $string = str_replace("\r\n", '', $string); // 清除换行符
  417. $string = str_replace("\n", '', $string); // 清除换行符
  418. $string = str_replace("\t", '', $string); // 清除制表符
  419. $string = str_replace(' ', '', $string); // 清除大空格
  420. $string = str_replace('&nbsp;', '', $string); // 清除 &nbsp;
  421. $string = preg_replace('/\s+/', ' ', $string); // 清除空格
  422. return $string;
  423. }
  424. // 去除字符串两端斜线
  425. function trim_slash($string)
  426. {
  427. return trim($string, '/');
  428. }
  429. // 驼峰转换下划线加小写字母
  430. function hump_to_underline($string)
  431. {
  432. return strtolower(preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $string));
  433. }
  434. // 转换对象为数组
  435. function object_to_array($object)
  436. {
  437. if($object === null){
  438. return [];
  439. }else{
  440. return json_decode(json_encode($object),true);
  441. }
  442. }
  443. // 转换数组为对象
  444. function array_to_object($array)
  445. {
  446. return json_decode(json_encode($array));
  447. }
  448. // 值是否在对象中
  449. function in_object($needle, $object)
  450. {
  451. foreach ($object as $value) {
  452. if ($needle == $value)
  453. return true;
  454. }
  455. }
  456. // 结果集中查找指定字段父节点是否存在
  457. function result_value_search($needle, $result, $skey)
  458. {
  459. foreach ($result as $key => $value) {
  460. if ($value->$skey == $needle) {
  461. return $key;
  462. }
  463. }
  464. return false;
  465. }
  466. // 多维数组合并
  467. function mult_array_merge($array1, $array2)
  468. {
  469. if (is_array($array2)) {
  470. foreach ($array2 as $key => $value) {
  471. if (is_array($value)) {
  472. if (array_key_exists($key, $array1)) {
  473. $array1[$key] = mult_array_merge($array1[$key], $value);
  474. } else {
  475. $array1[$key] = $value;
  476. }
  477. } else {
  478. $array1[$key] = $value;
  479. }
  480. }
  481. }
  482. return $array1;
  483. }
  484. // 数组转换为带引号字符串
  485. function implode_quot($glue, array $pieces, $diffnum = false)
  486. {
  487. if (! $pieces)
  488. return "''";
  489. foreach ($pieces as $key => $value) {
  490. if ($diffnum && ! is_numeric($value)) {
  491. $value = "'$value'";
  492. } elseif (! $diffnum) {
  493. $value = "'$value'";
  494. }
  495. if (isset($string)) {
  496. $string .= $glue . $value;
  497. } else {
  498. $string = $value;
  499. }
  500. }
  501. return $string;
  502. }
  503. // 是否为多维数组,是返回true
  504. function is_multi_array($array)
  505. {
  506. if (is_array($array)) {
  507. return (count($array) != count($array, 1));
  508. } else {
  509. return false;
  510. }
  511. }
  512. // 是否为移动设备
  513. function is_mobile()
  514. {
  515. $os = get_user_os();
  516. if ($os == 'Android' || $os == 'iPhone' || $os == 'Windows Phone' || $os == 'iPad') {
  517. return true;
  518. }
  519. }
  520. // 是否为POST请求
  521. function is_post()
  522. {
  523. if ($_POST) {
  524. return true;
  525. } else {
  526. return false;
  527. }
  528. }
  529. // 是否为GET请求
  530. function is_get()
  531. {
  532. if ($_GET) {
  533. return true;
  534. } else {
  535. return false;
  536. }
  537. }
  538. // 是否为PUT请求
  539. function is_put()
  540. {
  541. if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
  542. return true;
  543. } else {
  544. return false;
  545. }
  546. }
  547. // 是否为PATCH请求
  548. function is_patch()
  549. {
  550. if ($_SERVER['REQUEST_METHOD'] == 'PATCH') {
  551. return true;
  552. } else {
  553. return false;
  554. }
  555. }
  556. // 是否为DELETE请求
  557. function is_delete()
  558. {
  559. if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
  560. return true;
  561. } else {
  562. return false;
  563. }
  564. }
  565. // 是否为AJAX请求
  566. function is_ajax()
  567. {
  568. if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
  569. return true;
  570. } else {
  571. return false;
  572. }
  573. }
  574. // 判断当前是否为https
  575. function is_https()
  576. {
  577. if ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on')) {
  578. return true;
  579. } elseif (isset($_SERVER['REQUEST_SCHEME']) && strtolower($_SERVER['REQUEST_SCHEME']) == 'https') {
  580. return true;
  581. } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') {
  582. return true;
  583. } elseif (isset($_SERVER['HTTP_X_CLIENT_SCHEME']) && strtolower($_SERVER['HTTP_X_CLIENT_SCHEME']) == 'https') {
  584. return true;
  585. } else {
  586. return false;
  587. }
  588. }
  589. // 获取当前访问地址
  590. function get_http_url($noport = false)
  591. {
  592. if (is_https()) {
  593. $url = 'https://' . $_SERVER['HTTP_HOST'];
  594. } else {
  595. $url = 'http://' . $_SERVER['HTTP_HOST'];
  596. }
  597. if ($noport) {
  598. $url = str_replace(':' . $_SERVER['SERVER_PORT'], '', $url);
  599. }
  600. return $url;
  601. }
  602. // 获取当前访问域名
  603. function get_http_host($noport = true)
  604. {
  605. if ($noport) {
  606. return str_replace(':' . $_SERVER['SERVER_PORT'], '', $_SERVER['HTTP_HOST']);
  607. } else {
  608. return $_SERVER['HTTP_HOST'];
  609. }
  610. }
  611. // 服务器信息
  612. function get_server_info()
  613. {
  614. // 定义输出常量
  615. define('YES', 'Yes');
  616. define('NO', '<span style="color:red">No</span>');
  617. // 服务器系统
  618. $data['php_os'] = PHP_OS;
  619. // 服务器访问地址
  620. $data['http_host'] = $_SERVER['HTTP_HOST'];
  621. // 服务器名称
  622. $data['server_name'] = $_SERVER['SERVER_NAME'];
  623. // 服务器端口
  624. $data['server_port'] = $_SERVER['SERVER_PORT'];
  625. // 服务器地址
  626. $data['server_addr'] = isset($_SERVER['LOCAL_ADDR']) ? $_SERVER['LOCAL_ADDR'] : $_SERVER['SERVER_ADDR'];
  627. // 服务器软件
  628. $data['server_software'] = $_SERVER['SERVER_SOFTWARE'];
  629. // 站点目录
  630. $data['document_root'] = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : DOC_PATH;
  631. // PHP版本
  632. $data['php_version'] = PHP_VERSION;
  633. // 数据库驱动
  634. $data['db_driver'] = Config::get('database.type');
  635. // php配置文件
  636. $data['php_ini'] = @php_ini_loaded_file();
  637. // 最大上传
  638. $data['upload_max_filesize'] = ini_get('upload_max_filesize');
  639. // 最大提交
  640. $data['post_max_size'] = ini_get('post_max_size');
  641. // 最大提交文件数
  642. $data['max_file_uploads'] = ini_get('max_file_uploads');
  643. // 内存限制
  644. $data['memory_limit'] = ini_get('memory_limit');
  645. // 检测gd扩展
  646. $data['gd'] = extension_loaded('gd') ? YES : NO;
  647. // 检测imap扩展
  648. $data['imap'] = extension_loaded('imap') ? YES : NO;
  649. // 检测socket扩展
  650. $data['sockets'] = extension_loaded('sockets') ? YES : NO;
  651. // 检测curl扩展
  652. $data['curl'] = extension_loaded('curl') ? YES : NO;
  653. // 会话保存路径
  654. $data['session_save_path'] = session_save_path() ?: $_SERVER['TMP'];
  655. // 检测standard库是否存在
  656. $data['standard'] = extension_loaded('standard') ? YES : NO;
  657. // 检测多线程支持
  658. $data['pthreads'] = extension_loaded('pthreads') ? YES : NO;
  659. // 检测XCache支持
  660. $data['xcache'] = extension_loaded('XCache') ? YES : NO;
  661. // 检测APC支持
  662. $data['apc'] = extension_loaded('APC') ? YES : NO;
  663. // 检测eAccelerator支持
  664. $data['eaccelerator'] = extension_loaded('eAccelerator') ? YES : NO;
  665. // 检测wincache支持
  666. $data['wincache'] = extension_loaded('wincache') ? YES : NO;
  667. // 检测ZendOPcache支持
  668. $data['zendopcache'] = extension_loaded('Zend OPcache') ? YES : NO;
  669. // 检测memcache支持
  670. $data['memcache'] = extension_loaded('memcache') ? YES : NO;
  671. // 检测memcached支持
  672. $data['memcached'] = extension_loaded('memcached') ? YES : NO;
  673. // 已经安装模块
  674. $loaded_extensions = get_loaded_extensions();
  675. $extensions = '';
  676. foreach ($loaded_extensions as $key => $value) {
  677. $extensions .= $value . ', ';
  678. }
  679. $data['extensions'] = $extensions;
  680. return json_decode(json_encode($data));
  681. }
  682. // 获取数据库类型
  683. function get_db_type()
  684. {
  685. switch (Config::get('database.type')) {
  686. case 'mysqli':
  687. case 'pdo_mysql':
  688. $db = 'mysql';
  689. break;
  690. case 'sqlite':
  691. case 'pdo_sqlite':
  692. $db = 'sqlite';
  693. break;
  694. case 'pdo_pgsql':
  695. $db = 'pgsql';
  696. break;
  697. default:
  698. $db = null;
  699. }
  700. return $db;
  701. }
  702. // 获取间隔的月份的起始及结束日期
  703. function get_month_days($date, $start = 0, $interval = 1, $retamp = false)
  704. {
  705. $timestamp = strtotime($date) ?: $date;
  706. $first_day = strtotime(date('Y', $timestamp) . '-' . date('m', $timestamp) . '-01 +' . $start . ' month');
  707. $last_day = strtotime(date('Y-m-d', $first_day) . ' +' . $interval . ' month -1 day');
  708. if ($retamp) {
  709. $return = array(
  710. 'first' => $first_day,
  711. 'last' => $last_day
  712. );
  713. } else {
  714. $return = array(
  715. 'first' => date('Y-m-d', $first_day),
  716. 'last' => date('Y-m-d', $last_day)
  717. );
  718. }
  719. return $return;
  720. }
  721. // 框架地址地址前缀
  722. function url_index_path($indexfile = null)
  723. {
  724. $indexfile = $indexfile ?: $_SERVER["SCRIPT_NAME"];
  725. if (Config::get('app_url_type') == 2 && strripos($indexfile, 'index.php') !== false) {
  726. return SITE_DIR;
  727. } elseif (Config::get('app_url_type') == 3 && strripos($indexfile, 'index.php') !== false) {
  728. return SITE_DIR . '/?p=';
  729. } elseif (Config::get('app_url_type') == 3 && strripos($indexfile, 'index.php') === false) {
  730. return $indexfile . '?p=';
  731. } else {
  732. return $indexfile;
  733. }
  734. }
  735. // 获取服务端web软件
  736. function get_server_soft()
  737. {
  738. $soft = strtolower($_SERVER["SERVER_SOFTWARE"]);
  739. if (strpos($soft, 'iis')) {
  740. return 'iis';
  741. } elseif (strpos($soft, 'apache')) {
  742. return 'apache';
  743. } elseif (strpos($soft, 'nginx')) {
  744. return 'nginx';
  745. } else {
  746. return 'other';
  747. }
  748. }
  749. // 创建会话层级目录
  750. function create_session_dir($path, $depth)
  751. {
  752. if ($depth < 1) {
  753. return;
  754. } else {
  755. $depth --;
  756. }
  757. $char = array(
  758. 0,
  759. 1,
  760. 2,
  761. 3,
  762. 4,
  763. 5,
  764. 6,
  765. 7,
  766. 8,
  767. 9,
  768. 'a',
  769. 'b',
  770. 'c',
  771. 'd',
  772. 'e',
  773. 'f',
  774. 'g',
  775. 'h',
  776. 'i',
  777. 'j',
  778. 'k',
  779. 'l',
  780. 'm',
  781. 'n',
  782. 'o',
  783. 'p',
  784. 'q',
  785. 'r',
  786. 's',
  787. 't',
  788. 'u',
  789. 'v'
  790. );
  791. foreach ($char as $value) {
  792. if (! check_dir($path . '/' . $value, true)) {
  793. error('会话目录写入权限不足!');
  794. }
  795. create_session_dir($path . '/' . $value, $depth);
  796. }
  797. }
  798. // 中英混合的字符串截取,以一个汉字为一个单位长度,英文为半个
  799. function substr_both($string, $strat, $length)
  800. {
  801. $s = 0; // 起始位置
  802. $i = 0; // 实际Byte计数
  803. $n = 0; // 字符串长度计数
  804. $str_length = strlen($string); // 字符串的字节长度
  805. while (($n < $length) and ($i < $str_length)) {
  806. $ascnum = Ord(substr($string, $i, 1)); // 得到字符串中第$i位字符的ascii码
  807. if ($ascnum >= 224) { // 根据UTF-8编码规范,将3个连续的字符计为单个字符
  808. $i += 3;
  809. $n ++;
  810. } elseif ($ascnum >= 192) { // 根据UTF-8编码规范,将2个连续的字符计为单个字符
  811. $i += 2;
  812. $n ++;
  813. } else {
  814. $i += 1;
  815. $n += 0.5;
  816. }
  817. if ($s == 0 && $strat > 0 && $n >= $strat) {
  818. $s = $i; // 记录起始位置
  819. }
  820. }
  821. if ($n < $strat) { // 起始位置大于字符串长度
  822. return;
  823. }
  824. return substr($string, $s, $i);
  825. }
  826. // 中英混合的字符串长度,以一个汉字为一个单位长度,英文为半个
  827. function strlen_both($string)
  828. {
  829. $i = 0; // 实际Byte计数
  830. $n = 0; // 字符串长度计数
  831. $str_length = strlen($string); // 字符串的字节长度
  832. while ($i < $str_length) {
  833. $ascnum = Ord(substr($string, $i, 1)); // 得到字符串中第$i位字符的ascii码
  834. if ($ascnum >= 224) { // 根据UTF-8编码规范,将3个连续的字符计为单个字符
  835. $i += 3;
  836. $n ++;
  837. } elseif ($ascnum >= 192) { // 根据UTF-8编码规范,将2个连续的字符计为单个字符
  838. $i += 2;
  839. $n ++;
  840. } else {
  841. $i += 1;
  842. $n += 0.5;
  843. }
  844. }
  845. return $n;
  846. }
  847. // 获取地址参数
  848. function query_string($unset = null)
  849. {
  850. if (isset($_SERVER["QUERY_STRING"]) && ! ! $qs = $_SERVER["QUERY_STRING"]) {
  851. parse_str($qs, $output);
  852. unset($output['page']);
  853. $unset = strpos($unset, ',') ? explode(',', $unset) : $unset;
  854. if (is_array($unset)) {
  855. foreach ($unset as $value) {
  856. if (isset($output[$value])) {
  857. unset($output[$value]);
  858. }
  859. }
  860. } else {
  861. if (isset($output[$unset])) {
  862. unset($output[$unset]);
  863. }
  864. }
  865. // 避免路径参数编码
  866. if (isset($output['p'])) {
  867. $p = 'p=' . $output['p'];
  868. unset($output['p']);
  869. $qs = $output ? $p . '&' . http_build_query($output) : $p;
  870. } else {
  871. $qs = http_build_query($output);
  872. }
  873. }
  874. return $qs ? '?' . $qs : '';
  875. }
  876. // 判断是否在子网
  877. function network_match($ip, $network)
  878. {
  879. if (strpos($network, '/') > 0) {
  880. $network = explode('/', $network);
  881. $move = 32 - $network[1];
  882. if ($network[1] == 0) {
  883. return true;
  884. }
  885. return ((ip2long($ip) >> $move) === (ip2long($network[0]) >> $move)) ? true : false;
  886. } elseif ($network == $ip) {
  887. return true;
  888. } else {
  889. return false;
  890. }
  891. }
  892. // 递归替换
  893. function preg_replace_r($search, $replace, $subject)
  894. {
  895. while (preg_match($search, $subject)) {
  896. $subject = preg_replace($search, $replace, $subject);
  897. }
  898. return $subject;
  899. }
  900. // 生成随机验证码
  901. function create_code($len = 4)
  902. {
  903. $charset = 'ABCDEFGHKMNPRTUVWXY23456789';
  904. $charset = str_shuffle($charset);
  905. $charlen = strlen($charset) - 1;
  906. $code = '';
  907. for ($i = 0; $i < $len; $i ++) {
  908. $code .= $charset[mt_rand(0, $charlen)];
  909. }
  910. return $code;
  911. }