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

908 рядки
25 KiB

  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()
  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 = 'unknow';
  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, 2);
  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, $time)
  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. return $tpl_content;
  339. } else {
  340. exit('<div style="font-size:50px;">:(</div>提示信息的模板文件不存在!');
  341. }
  342. }
  343. // 获取转义数据,支持字符串、数组、对象
  344. function escape_string($string)
  345. {
  346. if (! $string)
  347. return $string;
  348. if (is_array($string)) { // 数组处理
  349. foreach ($string as $key => $value) {
  350. $string[$key] = escape_string($value);
  351. }
  352. } elseif (is_object($string)) { // 对象处理
  353. foreach ($string as $key => $value) {
  354. $string->$key = escape_string($value);
  355. }
  356. } else { // 字符串处理
  357. $string = htmlspecialchars(trim($string), ENT_QUOTES, 'UTF-8');
  358. $string = addslashes($string);
  359. }
  360. return $string;
  361. }
  362. // 字符反转义html实体及斜杠,支持字符串、数组、对象
  363. function decode_string($string)
  364. {
  365. if (! $string)
  366. return $string;
  367. if (is_array($string)) { // 数组处理
  368. foreach ($string as $key => $value) {
  369. $string[$key] = decode_string($value);
  370. }
  371. } elseif (is_object($string)) { // 对象处理
  372. foreach ($string as $key => $value) {
  373. $string->$key = decode_string($value);
  374. }
  375. } else { // 字符串处理
  376. $string = stripcslashes($string);
  377. $string = htmlspecialchars_decode($string, ENT_QUOTES);
  378. }
  379. return $string;
  380. }
  381. // 字符反转义斜杠,支持字符串、数组、对象
  382. function decode_slashes($string)
  383. {
  384. if (! $string)
  385. return $string;
  386. if (is_array($string)) { // 数组处理
  387. foreach ($string as $key => $value) {
  388. $string[$key] = decode_slashes($value);
  389. }
  390. } elseif (is_object($string)) { // 对象处理
  391. foreach ($string as $key => $value) {
  392. $string->$key = decode_slashes($value);
  393. }
  394. } else { // 字符串处理
  395. $string = stripcslashes($string);
  396. }
  397. return $string;
  398. }
  399. // 字符串双层MD5加密
  400. function encrypt_string($string)
  401. {
  402. return md5(md5($string));
  403. }
  404. // 生成唯一标识符
  405. function get_uniqid()
  406. {
  407. return encrypt_string(uniqid(mt_rand(), true));
  408. }
  409. // 清洗html代码的空白符号
  410. function clear_html_blank($string)
  411. {
  412. $string = str_replace("\r\n", '', $string); // 清除换行符
  413. $string = str_replace("\n", '', $string); // 清除换行符
  414. $string = str_replace("\t", '', $string); // 清除制表符
  415. $string = str_replace(' ', '', $string); // 清除大空格
  416. $string = str_replace('&nbsp;', '', $string); // 清除 &nbsp;
  417. $string = preg_replace('/\s+/', ' ', $string); // 清除空格
  418. return $string;
  419. }
  420. // 去除字符串两端斜线
  421. function trim_slash($string)
  422. {
  423. return trim($string, '/');
  424. }
  425. // 驼峰转换下划线加小写字母
  426. function hump_to_underline($string)
  427. {
  428. return strtolower(preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $string));
  429. }
  430. // 转换对象为数组
  431. function object_to_array($object)
  432. {
  433. return json_decode(json_encode($object), true);
  434. }
  435. // 转换数组为对象
  436. function array_to_object($array)
  437. {
  438. return json_decode(json_encode($array));
  439. }
  440. // 值是否在对象中
  441. function in_object($needle, $object)
  442. {
  443. foreach ($object as $value) {
  444. if ($needle == $value)
  445. return true;
  446. }
  447. }
  448. // 结果集中查找指定字段父节点是否存在
  449. function result_value_search($needle, $result, $skey)
  450. {
  451. foreach ($result as $key => $value) {
  452. if ($value->$skey == $needle) {
  453. return $key;
  454. }
  455. }
  456. return false;
  457. }
  458. // 多维数组合并
  459. function mult_array_merge($array1, $array2)
  460. {
  461. if (is_array($array2)) {
  462. foreach ($array2 as $key => $value) {
  463. if (is_array($value)) {
  464. if (array_key_exists($key, $array1)) {
  465. $array1[$key] = mult_array_merge($array1[$key], $value);
  466. } else {
  467. $array1[$key] = $value;
  468. }
  469. } else {
  470. $array1[$key] = $value;
  471. }
  472. }
  473. }
  474. return $array1;
  475. }
  476. // 数组转换为带引号字符串
  477. function implode_quot($glue, array $pieces, $diffnum = false)
  478. {
  479. if (! $pieces)
  480. return "''";
  481. foreach ($pieces as $key => $value) {
  482. if ($diffnum && ! is_numeric($value)) {
  483. $value = "'$value'";
  484. } elseif (! $diffnum) {
  485. $value = "'$value'";
  486. }
  487. if (isset($string)) {
  488. $string .= $glue . $value;
  489. } else {
  490. $string = $value;
  491. }
  492. }
  493. return $string;
  494. }
  495. // 是否为多维数组,是返回true
  496. function is_multi_array($array)
  497. {
  498. if (is_array($array)) {
  499. return (count($array) != count($array, 1));
  500. } else {
  501. return false;
  502. }
  503. }
  504. // 是否为移动设备
  505. function is_mobile()
  506. {
  507. $os = get_user_os();
  508. if ($os == 'Android' || $os == 'iPhone' || $os == 'Windows Phone' || $os == 'iPad') {
  509. return true;
  510. }
  511. }
  512. // 是否为POST请求
  513. function is_post()
  514. {
  515. if ($_POST) {
  516. return true;
  517. } else {
  518. return false;
  519. }
  520. }
  521. // 是否为GET请求
  522. function is_get()
  523. {
  524. if ($_GET) {
  525. return true;
  526. } else {
  527. return false;
  528. }
  529. }
  530. // 是否为PUT请求
  531. function is_put()
  532. {
  533. if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
  534. return true;
  535. } else {
  536. return false;
  537. }
  538. }
  539. // 是否为PATCH请求
  540. function is_patch()
  541. {
  542. if ($_SERVER['REQUEST_METHOD'] == 'PATCH') {
  543. return true;
  544. } else {
  545. return false;
  546. }
  547. }
  548. // 是否为DELETE请求
  549. function is_delete()
  550. {
  551. if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
  552. return true;
  553. } else {
  554. return false;
  555. }
  556. }
  557. // 是否为AJAX请求
  558. function is_ajax()
  559. {
  560. if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
  561. return true;
  562. } else {
  563. return false;
  564. }
  565. }
  566. // 判断当前是否为https
  567. function is_https()
  568. {
  569. if ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) {
  570. return true;
  571. } else {
  572. return false;
  573. }
  574. }
  575. // 获取当前访问地址
  576. function get_http_url($noport = false)
  577. {
  578. if (is_https()) {
  579. $url = 'https://' . $_SERVER['HTTP_HOST'];
  580. } else {
  581. $url = 'http://' . $_SERVER['HTTP_HOST'];
  582. }
  583. if ($noport) {
  584. $url = str_replace(':' . $_SERVER['SERVER_PORT'], '', $url);
  585. }
  586. return $url;
  587. }
  588. // 获取当前访问域名
  589. function get_http_host()
  590. {
  591. return str_replace(':' . $_SERVER['SERVER_PORT'], '', $_SERVER['HTTP_HOST']);
  592. }
  593. // 服务器信息
  594. function get_server_info()
  595. {
  596. // 定义输出常量
  597. define('YES', 'Yes');
  598. define('NO', '<span style="color:red">No</span>');
  599. // 服务器系统
  600. $data['php_os'] = PHP_OS;
  601. // 服务器访问地址
  602. $data['http_host'] = $_SERVER['HTTP_HOST'];
  603. // 服务器名称
  604. $data['server_name'] = $_SERVER['SERVER_NAME'];
  605. // 服务器端口
  606. $data['server_port'] = $_SERVER['SERVER_PORT'];
  607. // 服务器地址
  608. $data['server_addr'] = isset($_SERVER['LOCAL_ADDR']) ? $_SERVER['LOCAL_ADDR'] : $_SERVER['SERVER_ADDR'];
  609. // 服务器软件
  610. $data['server_software'] = $_SERVER['SERVER_SOFTWARE'];
  611. // 站点目录
  612. $data['document_root'] = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : DOC_PATH;
  613. // PHP版本
  614. $data['php_version'] = PHP_VERSION;
  615. // 数据库驱动
  616. $data['db_driver'] = Config::get('database.type');
  617. // php配置文件
  618. $data['php_ini'] = @php_ini_loaded_file();
  619. // 最大上传
  620. $data['upload_max_filesize'] = ini_get('upload_max_filesize');
  621. // 最大提交
  622. $data['post_max_size'] = ini_get('post_max_size');
  623. // 最大提交文件数
  624. $data['max_file_uploads'] = ini_get('max_file_uploads');
  625. // 内存限制
  626. $data['memory_limit'] = ini_get('memory_limit');
  627. // 检测gd扩展
  628. $data['gd'] = extension_loaded('gd') ? YES : NO;
  629. // 检测imap扩展
  630. $data['imap'] = extension_loaded('imap') ? YES : NO;
  631. // 检测socket扩展
  632. $data['sockets'] = extension_loaded('sockets') ? YES : NO;
  633. // 检测curl扩展
  634. $data['curl'] = extension_loaded('curl') ? YES : NO;
  635. // 会话保存路径
  636. $data['session_save_path'] = session_save_path() ?: $_SERVER['TMP'];
  637. // 检测standard库是否存在
  638. $data['standard'] = extension_loaded('standard') ? YES : NO;
  639. // 检测多线程支持
  640. $data['pthreads'] = extension_loaded('pthreads') ? YES : NO;
  641. // 检测XCache支持
  642. $data['xcache'] = extension_loaded('XCache') ? YES : NO;
  643. // 检测APC支持
  644. $data['apc'] = extension_loaded('APC') ? YES : NO;
  645. // 检测eAccelerator支持
  646. $data['eaccelerator'] = extension_loaded('eAccelerator') ? YES : NO;
  647. // 检测wincache支持
  648. $data['wincache'] = extension_loaded('wincache') ? YES : NO;
  649. // 检测ZendOPcache支持
  650. $data['zendopcache'] = extension_loaded('Zend OPcache') ? YES : NO;
  651. // 检测memcache支持
  652. $data['memcache'] = extension_loaded('memcache') ? YES : NO;
  653. // 检测memcached支持
  654. $data['memcached'] = extension_loaded('memcached') ? YES : NO;
  655. // 已经安装模块
  656. $loaded_extensions = get_loaded_extensions();
  657. $extensions = '';
  658. foreach ($loaded_extensions as $key => $value) {
  659. $extensions .= $value . ', ';
  660. }
  661. $data['extensions'] = $extensions;
  662. return json_decode(json_encode($data));
  663. }
  664. // 获取数据库类型
  665. function get_db_type()
  666. {
  667. switch (Config::get('database.type')) {
  668. case 'mysqli':
  669. case 'pdo_mysql':
  670. $db = 'mysql';
  671. break;
  672. case 'sqlite':
  673. case 'pdo_sqlite':
  674. $db = 'sqlite';
  675. break;
  676. case 'pdo_pgsql':
  677. $db = 'pgsql';
  678. break;
  679. default:
  680. $db = null;
  681. }
  682. return $db;
  683. }
  684. // 获取间隔的月份的起始及结束日期
  685. function get_month_days($date, $start = 0, $interval = 1, $retamp = false)
  686. {
  687. $timestamp = strtotime($date) ?: $date;
  688. $first_day = strtotime(date('Y', $timestamp) . '-' . date('m', $timestamp) . '-01 +' . $start . ' month');
  689. $last_day = strtotime(date('Y-m-d', $first_day) . ' +' . $interval . ' month -1 day');
  690. if ($retamp) {
  691. $return = array(
  692. 'first' => $first_day,
  693. 'last' => $last_day
  694. );
  695. } else {
  696. $return = array(
  697. 'first' => date('Y-m-d', $first_day),
  698. 'last' => date('Y-m-d', $last_day)
  699. );
  700. }
  701. return $return;
  702. }
  703. // 是否伪静态模式
  704. function is_rewrite()
  705. {
  706. $indexfile = $_SERVER["SCRIPT_NAME"];
  707. if (Config::get('url_type') == 2 && strrpos($indexfile, 'index.php') !== false) {
  708. return true;
  709. } else {
  710. return false;
  711. }
  712. }
  713. // 获取服务端web软件
  714. function get_server_soft()
  715. {
  716. $soft = strtolower($_SERVER["SERVER_SOFTWARE"]);
  717. if (strpos($soft, 'iis')) {
  718. return 'iis';
  719. } elseif (strpos($soft, 'apache')) {
  720. return 'apache';
  721. } elseif (strpos($soft, 'nginx')) {
  722. return 'nginx';
  723. } else {
  724. return 'other';
  725. }
  726. }
  727. // 创建会话层级目录
  728. function create_session_dir($path, $depth)
  729. {
  730. if ($depth < 1) {
  731. return;
  732. } else {
  733. $depth --;
  734. }
  735. $char = array(
  736. 0,
  737. 1,
  738. 2,
  739. 3,
  740. 4,
  741. 5,
  742. 6,
  743. 7,
  744. 8,
  745. 9,
  746. 'a',
  747. 'b',
  748. 'c',
  749. 'd',
  750. 'e',
  751. 'f',
  752. 'g',
  753. 'h',
  754. 'i',
  755. 'j',
  756. 'k',
  757. 'l',
  758. 'm',
  759. 'n',
  760. 'o',
  761. 'p',
  762. 'q',
  763. 'r',
  764. 's',
  765. 't',
  766. 'u',
  767. 'v'
  768. );
  769. foreach ($char as $value) {
  770. if (! check_dir($path . '/' . $value, true)) {
  771. error('会话目录写入权限不足!');
  772. }
  773. create_session_dir($path . '/' . $value, $depth);
  774. }
  775. }
  776. // 中英混合的字符串截取,以一个汉字为一个单位长度,英文为半个
  777. function substr_both($string, $strat, $length)
  778. {
  779. $s = 0; // 起始位置
  780. $i = 0; // 实际Byte计数
  781. $n = 0; // 字符串长度计数
  782. $str_length = strlen($string); // 字符串的字节长度
  783. while (($n < $length) and ($i < $str_length)) {
  784. $ascnum = Ord(substr($string, $i, 1)); // 得到字符串中第$i位字符的ascii码
  785. if ($ascnum >= 224) { // 根据UTF-8编码规范,将3个连续的字符计为单个字符
  786. $i += 3;
  787. $n ++;
  788. } elseif ($ascnum >= 192) { // 根据UTF-8编码规范,将2个连续的字符计为单个字符
  789. $i += 2;
  790. $n ++;
  791. } else {
  792. $i += 1;
  793. $n += 0.5;
  794. }
  795. if ($s == 0 && $strat > 0 && $n >= $strat) {
  796. $s = $i; // 记录起始位置
  797. }
  798. }
  799. if ($n < $strat) { // 起始位置大于字符串长度
  800. return;
  801. }
  802. return substr($string, $s, $i);
  803. }
  804. // 中英混合的字符串长度,以一个汉字为一个单位长度,英文为半个
  805. function strlen_both($string)
  806. {
  807. $i = 0; // 实际Byte计数
  808. $n = 0; // 字符串长度计数
  809. $str_length = strlen($string); // 字符串的字节长度
  810. while ($i < $str_length) {
  811. $ascnum = Ord(substr($string, $i, 1)); // 得到字符串中第$i位字符的ascii码
  812. if ($ascnum >= 224) { // 根据UTF-8编码规范,将3个连续的字符计为单个字符
  813. $i += 3;
  814. $n ++;
  815. } elseif ($ascnum >= 192) { // 根据UTF-8编码规范,将2个连续的字符计为单个字符
  816. $i += 2;
  817. $n ++;
  818. } else {
  819. $i += 1;
  820. $n += 0.5;
  821. }
  822. }
  823. return $n;
  824. }
  825. // 缓存配置
  826. function cache_config($refresh = false)
  827. {
  828. // 系统配置缓存
  829. $config_cache = RUN_PATH . '/config/' . md5('config') . '.php';
  830. if (! file_exists($config_cache) || $refresh) {
  831. $model = model('admin.system.Config');
  832. Config::set(md5('config'), $model->getConfig(), false);
  833. }
  834. Config::assign($config_cache); // 注入配置
  835. }
  836. // 递归替换
  837. function preg_replace_r($search, $replace, $subject)
  838. {
  839. while (preg_match($search, $subject)) {
  840. $subject = preg_replace($search, $replace, $subject);
  841. }
  842. return $subject;
  843. }