Functions.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188
  1. <?php
  2. function getArrayItem(array $array,$key = 0, $defaultValue = '')
  3. {
  4. if (!is_array($array)){
  5. return $defaultValue;
  6. }
  7. return (isset($array[$key]) && !empty($array[$key])) ? $array[$key] : $defaultValue;
  8. }
  9. function loadFile($filepath, $return = false)
  10. {
  11. if (file_exists($filepath)) {
  12. if ($return) {
  13. return include $filepath;
  14. } else {
  15. include $filepath;
  16. }
  17. } else {
  18. throw new \Exception($filepath . ' file cannot be found');
  19. }
  20. }
  21. function xssCheck()
  22. {
  23. if (isset($_SERVER['REQUEST_URI'])) {
  24. $temp = strtoupper(urldecode(urldecode($_SERVER['REQUEST_URI'])));
  25. if (strpos($temp, '<') !== false || strpos($temp, '"') !== false || strpos($temp, 'CONTENT-TRANSFER-ENCODING') !== false) {
  26. throw new \Exception('request_tainting' . $temp);
  27. }
  28. }
  29. return true;
  30. }
  31. /**
  32. * @param $module string 服务模块名
  33. * @throws Exception
  34. */
  35. function loadServiceConfig($module)
  36. {
  37. if (!$module) {
  38. throw new \Exception('module not null');
  39. }
  40. $serviceConfig = ROOT_PATH . DS . '..' . DS . 'Service' . DS . ucfirst($module) . DS . 'Config.php';
  41. return loadFile($serviceConfig, true);
  42. }
  43. /**
  44. * 写入php错误日志
  45. *
  46. * @param string $errno 错误编号
  47. * @param string $errmsg 错误信息
  48. * @param string $filename 错误文件
  49. * @param string $linenum 错误行数
  50. * @param mixed $vars 错误参数
  51. *
  52. */
  53. function php_error_log($errno, $errmsg, $filename, $linenum, $vars)
  54. {
  55. if (!defined('E_STRICT')) define('E_STRICT', 2048);
  56. $errortype = array(
  57. E_ERROR => 'Error',
  58. E_WARNING => 'Warning',
  59. E_PARSE => 'Parsing Error',
  60. E_NOTICE => 'Notice',
  61. E_CORE_ERROR => 'Core Error',
  62. E_CORE_WARNING => 'Core Warning',
  63. E_COMPILE_ERROR => 'Compile Error',
  64. E_COMPILE_WARNING => 'Compile Warning',
  65. E_USER_ERROR => 'User Error',
  66. E_USER_WARNING => 'User Warning',
  67. E_USER_NOTICE => 'User Notice',
  68. E_STRICT => 'Runtime Notice'
  69. );
  70. $user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);
  71. $filename = str_replace("\\", '/', $filename);
  72. $dt = date('Y-m-d H:i:s');
  73. $err = "#####" . $dt . "\n";
  74. $err .= "```" . "\n";
  75. $err .= "datetime :" . $dt . "\n";
  76. $err .= "errornum :" . $errno . "\n";
  77. $err .= "errormsg :" . $errortype[$errno] . "\n";
  78. $err .= "errortype :" . $errmsg . "\n";
  79. $err .= "scriptname :" . $filename . "\n";
  80. if (in_array($errno, $user_errors)) {
  81. $err .= "scriptname :" . wddx_serialize_value($vars, "Variables") . "\n";
  82. }
  83. $err .= "scriptlinenum:" . $linenum . "\n";
  84. $err .= "```\n";
  85. $logDir = PROJECT_PATH . DS . 'Storage' . DS . 'Logs' . DS . 'SysError' . DS;
  86. $logFile = $logDir . date('m-d') . '.md';
  87. if (!is_dir($logDir)) {
  88. @mkdir($logDir);
  89. }
  90. @error_log($err, 3, $logFile);
  91. @chmod($logFile, 0777);
  92. }
  93. function shutdown_function()
  94. {
  95. $e = error_get_last();
  96. if (isset($e['type'])) {
  97. if (in_array($e['type'], array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR))) {
  98. php_error_log($e['type'], $e['message'], $e['file'], $e['line'], NULL);
  99. }
  100. }
  101. }
  102. if (defined('LOG_ERROR') && LOG_ERROR) {
  103. register_shutdown_function('shutdown_function');
  104. }
  105. function isMobile($mobile)
  106. {
  107. return preg_match('#^13[\d]{9}$|^14[5,7]{1}\d{8}$|^15[^4]{1}\d{8}$|^16[\d]{9}$|^17[0,6,7,8,3,5]{1}\d{8}$|^18[\d]{9}$|^19[\d]{9}$#', $mobile)
  108. ? true
  109. : false;
  110. }
  111. /**电子邮箱格式校验*/
  112. function isEmail($email)
  113. {
  114. $pattern = "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i";
  115. return preg_match_all($pattern, $email) ? true : false;
  116. }
  117. /**
  118. * 利用curl模拟浏览器发送请求
  119. *
  120. * @param string $url 请求的URL
  121. * @param array|string $post post数据
  122. * @param int $timeout 执行超时时间
  123. * @param boolean $sendcookie 是否发送当前cookie
  124. * @param array $options 可选的CURL参数
  125. * @return array
  126. */
  127. function request($url, $post = null, $timeout = 40, $sendcookie = true, $options = array(), $ssl = false, $sslDate = array(), $useragent = false, $proxy = false, $http_build_query = true)
  128. {
  129. if (empty($useragent)) {
  130. if (isset($_SERVER['HTTP_USER_AGENT'])) {
  131. $useragent = $_SERVER['HTTP_USER_AGENT'];
  132. } else {
  133. $useragent = 'internalloginuseragent';
  134. }
  135. }
  136. if ($proxy) {
  137. $ip_long = array(
  138. array('607649792', '608174079'), //36.56.0.0-36.63.255.255
  139. array('1038614528', '1039007743'), //61.232.0.0-61.237.255.255
  140. array('1783627776', '1784676351'), //106.80.0.0-106.95.255.255
  141. array('2035023872', '2035154943'), //121.76.0.0-121.77.255.255
  142. array('2078801920', '2079064063'), //123.232.0.0-123.235.255.255
  143. array('-1950089216', '-1948778497'), //139.196.0.0-139.215.255.255
  144. array('-1425539072', '-1425014785'), //171.8.0.0-171.15.255.255
  145. array('-1236271104', '-1235419137'), //182.80.0.0-182.92.255.255
  146. array('-770113536', '-768606209'), //210.25.0.0-210.47.255.255
  147. array('-569376768', '-564133889'), //222.16.0.0-222.95.255.255
  148. );
  149. $rand_key = mt_rand(0, 9);
  150. $ip = long2ip(mt_rand($ip_long[$rand_key][0], $ip_long[$rand_key][1]));//随机生成国内某个ip
  151. $result = getNewProxyId();
  152. if ($result['error'] != '') {
  153. echo $result['error'];
  154. } else {
  155. $rand_ip = $result['ip'];
  156. }
  157. $baseHeader = array(
  158. "CLIENT-IP:{$ip}",
  159. "X-FORWARDED-FOR:{$ip}",
  160. );
  161. if (isset($options[CURLOPT_HTTPHEADER])) {
  162. $options[CURLOPT_HTTPHEADER] = array_merge($options[CURLOPT_HTTPHEADER], $baseHeader);
  163. }
  164. }
  165. $ch = curl_init($url);
  166. curl_setopt($ch, CURLOPT_HEADER, 0);
  167. curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
  168. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 35);
  169. curl_setopt($ch, CURLOPT_TIMEOUT, $timeout ? $timeout : 40);
  170. if (defined('CURLOPT_IPRESOLVE') && defined('CURL_IPRESOLVE_V4')) {
  171. curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
  172. }
  173. if ($sendcookie) {
  174. $cookie = '';
  175. foreach ($_COOKIE as $key => $val) {
  176. $cookie .= rawurlencode($key) . '=' . rawurlencode($val) . ';';
  177. }
  178. curl_setopt($ch, CURLOPT_COOKIE, $cookie);
  179. }
  180. if ($post) {
  181. curl_setopt($ch, CURLOPT_POST, 1);
  182. curl_setopt($ch, CURLOPT_POSTFIELDS, (is_array($post) && $http_build_query) ? http_build_query($post) : $post);
  183. }
  184. if (!ini_get('safe_mode') && ini_get('open_basedir') == '') {
  185. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  186. }
  187. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  188. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); //检查证书中是否设置域名且是否与提供的主机名匹配
  189. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); //是否只信任CA颁发的证书
  190. curl_setopt($ch, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
  191. if ($ssl) {
  192. /*curl_setopt($ch, CURLOPT_SSLCERT, '/apps/jindouyun/Public/upload/apiclient_cert.pem');
  193. curl_setopt($ch, CURLOPT_SSLKEY, '/apps/jindouyun/Public/upload/apiclient_key.pem');*/
  194. curl_setopt($ch, CURLOPT_SSLCERT, $sslDate['cert']);
  195. curl_setopt($ch, CURLOPT_SSLKEY, $sslDate['key']);
  196. }
  197. foreach ($options as $key => $value) {
  198. curl_setopt($ch, $key, $value);
  199. }
  200. if ($proxy && isset($rand_ip)) {
  201. curl_setopt($ch, CURLOPT_PROXY, 'http://' . $rand_ip);
  202. }
  203. $ret = curl_exec($ch);
  204. $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  205. $content_length = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
  206. if (!$content_length) $content_length = curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);
  207. $info = curl_getinfo($ch);
  208. $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
  209. $errorMsg = curl_error($ch);
  210. curl_close($ch);
  211. return array(
  212. 'httpcode' => $httpcode,
  213. 'info' => $info,
  214. 'errorMsg' => $errorMsg,
  215. 'content_length' => $content_length,
  216. 'content_type' => $content_type,
  217. 'content' => $ret
  218. );
  219. }
  220. /**
  221. * 获取最新的代理ip
  222. * 代理测试工具 http://proxies.site-digger.com/proxy-test/
  223. **/
  224. function getNewProxyId()
  225. {
  226. //$url = 'http://webapi.http.zhimacangku.com/getip?num=1&type=2&pro=&city=0&yys=0&port=1&time=1&ts=1&ys=1&cs=1&lb=1&sb=0&pb=4&mr=1&regions=';
  227. $url = 'http://http.tiqu.qingjuhe.cn/getip?num=1&type=2&pack=35299&port=1&lb=1&pb=4&regions=';
  228. $data = request($url);
  229. if ($data['httpcode'] == 200) {
  230. $content = json_decode($data['content'], true);
  231. if ($content['success'] == 'true') {
  232. foreach ($content['data'] as $key => $value) {
  233. $rand_ip = $value['ip'] . ':' . $value['port'];
  234. }
  235. } else {
  236. $errorMessage = '获取代理ip失败' . $content['code'] . $content['msg'] . PHP_EOL;
  237. }
  238. }
  239. if (isset($rand_ip)) {
  240. return [
  241. 'ip' => $rand_ip,
  242. 'error' => '',
  243. ];
  244. } else {
  245. return [
  246. 'ip' => '',
  247. 'error' => $errorMessage,
  248. ];
  249. }
  250. }
  251. /**
  252. * 获取当前毫秒时间戳
  253. */
  254. function msectime()
  255. {
  256. list($msec, $sec) = explode(' ', microtime());
  257. return (int)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
  258. }
  259. /**
  260. * 断点调试输出方法
  261. *
  262. * @param mixed $msg 输出的内容
  263. *
  264. * @return string
  265. */
  266. function V($msg)
  267. {
  268. echo "<pre>";
  269. var_export($msg);
  270. exit();
  271. }
  272. /**
  273. * 校验日期格式是否正确
  274. *
  275. * @param string $date 日期
  276. * @param array $formats 需要检验的格式数组
  277. *
  278. * @return bool|int
  279. */
  280. function checkDateIsValid($date, $formats = ["Y-m-d", "Y/m/d", "Y-m-d H:i:s", "Y/m/d H:i:s"])
  281. {
  282. $unixTime = strtotime($date);
  283. if (!$unixTime) {
  284. return false;
  285. }
  286. foreach ($formats as $format) {
  287. if (date($format, $unixTime) == $date) {
  288. return $unixTime;
  289. }
  290. }
  291. return false;
  292. }
  293. /**
  294. * 二维数组根据某个字段排序
  295. *
  296. * @param array $needArray 需要排序的二维数组
  297. * @param string $field 根据的字段排序
  298. * @param array $sort 排序规则ASC 升序 | DESC 降序
  299. *
  300. * @return array;
  301. */
  302. function arrayMultiSort(array $needArray, $field, $sort = 'ASC')
  303. {
  304. $rule = [];
  305. $arrSort = [];
  306. $sort = strtoupper($sort);
  307. $rule['direction'] = 'SORT_' . $sort;
  308. $rule['field'] = $field;
  309. foreach ($needArray AS $uniqid => $row) {
  310. foreach ($row AS $key => $value) {
  311. $arrSort[$key][$uniqid] = $value;
  312. }
  313. }
  314. if ($rule['direction']) {
  315. array_multisort($arrSort[$rule['field']], constant($rule['direction']), $needArray);
  316. }
  317. return $needArray;
  318. }
  319. /**
  320. * 利用firephp输出调试到header
  321. *
  322. * 需要安装:
  323. * firefox:FireBug | chrome:FirePHP for Chrome
  324. *
  325. * @param mixed $message 要输出的信息
  326. * @param bool $showtime 是否显示执行时间
  327. */
  328. function console($message, $showtime = false)
  329. {
  330. static $lasttime = TIME;
  331. static $_getInstance;
  332. $thistime = microtime(true);
  333. $usedtime = $thistime - $lasttime;
  334. $lasttime = $thistime;
  335. $label = $showtime ? sprintf("%09.5fs", $usedtime) : NULL;
  336. if (is_null($_getInstance)) {
  337. $_getInstance = \Mall\Framework\Core\FirePHP::getInstance(true);
  338. }
  339. $_getInstance->info($message, $label);
  340. }
  341. /**
  342. * 检测数组的值不允许为空
  343. *
  344. * @param array $params 需要检测的数组
  345. * @param array $checkKey 需要检测的key默认全部检测
  346. * @param array $excludeKey 过虑不检测的Key
  347. *
  348. * @return string
  349. */
  350. function checkNotEmpty($params, $excludeKey = [], $checkKey = [])
  351. {
  352. $newParams = [];
  353. if ($checkKey && is_array($checkKey)) {
  354. foreach ($checkKey as $key) {
  355. if (isset($params[$key])) {
  356. $newParams[$key] = $params[$key];
  357. }
  358. }
  359. }
  360. if ($newParams) {
  361. $params = $newParams;
  362. }
  363. if (is_array($params)) {
  364. foreach ($params as $k => $v) {
  365. if (in_array($k, $excludeKey, true)) {
  366. continue;
  367. }
  368. if (is_array($v)) {
  369. checkNotEmpty($v);
  370. }
  371. if (empty($v)) {
  372. return $k . ' 不允许为空';
  373. }
  374. }
  375. }
  376. }
  377. /**
  378. * 友好格式化时间
  379. * @param int $timestamp 时间
  380. * @param array $formats
  381. * @return string
  382. */
  383. function formatDateTime($timestamp, $formats = null)
  384. {
  385. if ($formats == null) {
  386. $formats = array(
  387. 'DAY' => '%s天前',
  388. 'DAY_HOUR' => '%s天%s小时前',
  389. 'HOUR' => '%s小时',
  390. 'HOUR_MINUTE' => '%s小时%s分前',
  391. 'MINUTE' => '%s分钟前',
  392. 'MINUTE_SECOND' => '%s分钟%s秒前',
  393. 'SECOND' => '%s秒前',
  394. );
  395. }
  396. /* 计算出时间差 */
  397. $seconds = time() - $timestamp;
  398. $minutes = floor($seconds / 60);
  399. $hours = floor($minutes / 60);
  400. $days = floor($hours / 24);
  401. if ($days > 0 && $days < 31) {
  402. $diffFormat = 'DAY';
  403. } elseif ($days == 0) {
  404. $diffFormat = ($hours > 0) ? 'HOUR' : 'MINUTE';
  405. if ($diffFormat == 'HOUR') {
  406. $diffFormat .= ($minutes > 0 && ($minutes - $hours * 60) > 0) ? '_MINUTE' : '';
  407. } else {
  408. $diffFormat = (($seconds - $minutes * 60) > 0 && $minutes > 0)
  409. ? $diffFormat . '_SECOND' : 'SECOND';
  410. }
  411. } else {
  412. $diffFormat = 'TURE_DATE_TIME';//超出30天, 正常时间显示
  413. }
  414. $dateDiff = null;
  415. switch ($diffFormat) {
  416. case 'DAY':
  417. $dateDiff = sprintf($formats[$diffFormat], $days);
  418. break;
  419. case 'DAY_HOUR':
  420. $dateDiff = sprintf($formats[$diffFormat], $days, $hours - $days * 60);
  421. break;
  422. case 'HOUR':
  423. $dateDiff = sprintf($formats[$diffFormat], $hours);
  424. break;
  425. case 'HOUR_MINUTE':
  426. $dateDiff = sprintf($formats[$diffFormat], $hours, $minutes - $hours * 60);
  427. break;
  428. case 'MINUTE':
  429. $dateDiff = sprintf($formats[$diffFormat], $minutes);
  430. break;
  431. case 'MINUTE_SECOND':
  432. $dateDiff = sprintf($formats[$diffFormat], $minutes, $seconds - $minutes * 60);
  433. break;
  434. case 'SECOND':
  435. $dateDiff = sprintf($formats[$diffFormat], $seconds);
  436. break;
  437. default:
  438. $dateDiff = date('Y-m-d H:i:s',$timestamp);
  439. }
  440. return $dateDiff;
  441. }
  442. /**
  443. * 数组交叉排序并合并
  444. *
  445. * @param array $needo
  446. * @param array $needt
  447. *
  448. * @return array
  449. */
  450. function sortCross(array $needo = [], array $needt = [])
  451. {
  452. $newData = [];
  453. $needoCount = count($needo);
  454. $needtCount = count($needt);
  455. $size = $needoCount > $needtCount ? $needoCount : $needtCount;
  456. for ($i = 0; $i < $size; $i++) {
  457. if (isset($needo[$i])) {
  458. array_push($newData, $needo[$i]);
  459. }
  460. if (isset($needt[$i])) {
  461. array_push($newData, $needt[$i]);
  462. }
  463. }
  464. return $newData;
  465. }
  466. /**
  467. * 二维数组去重
  468. *
  469. * @param $list
  470. * @param $key
  471. *
  472. * @return array
  473. */
  474. function assocUnique($list, $key)
  475. {
  476. $arr = array();
  477. for ($i = 0; $i < count($list); $i++) {
  478. if (isset($list[$i][$key])) {
  479. if (!isset($arr[$list[$i][$key]])) {
  480. $arr[$list[$i][$key]] = $list[$i];
  481. }
  482. }
  483. }
  484. return array_values($arr);
  485. }
  486. /**
  487. * 为相对路径的缩略图加绝对地址
  488. *
  489. * @param string|array $thumbs 图片集合
  490. * @param string $key 图片地址的Key
  491. *
  492. * @return array
  493. */
  494. function absoluteImg($thumbs, $key = '')
  495. {
  496. if ($thumbs) {
  497. if (is_array($thumbs)) {
  498. foreach ($thumbs as &$t) {
  499. if ($key) {
  500. $value = $t[$key];
  501. } else {
  502. $value = $t;
  503. }
  504. if (!$value) {
  505. continue;
  506. }
  507. if (!filter_var($value, FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED)) {
  508. if ($key) {
  509. $t[$key] = URL_UPLOAD . $value;
  510. } else {
  511. $t = URL_UPLOAD . $value;
  512. }
  513. }
  514. }
  515. }
  516. if (is_string($thumbs)) {
  517. if (!filter_var($thumbs, FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED)) {
  518. $thumbs = URL_UPLOAD . $thumbs;
  519. }
  520. }
  521. }
  522. return $thumbs;
  523. }
  524. /**
  525. * 对内容字段进行 int 整形转换
  526. *
  527. * @param array $params
  528. *
  529. * @return array
  530. */
  531. function contentIntValFormat(array $params)
  532. {
  533. $intVal = [
  534. 'id',
  535. 'appid',
  536. 'has_thumb',
  537. 'catid',
  538. 'created',
  539. 'createdby',
  540. 'published',
  541. 'publishedby',
  542. 'modified',
  543. 'modifiedby',
  544. 'digg',
  545. 'pv',
  546. 'virtual_pv',
  547. 'status',
  548. 'indexid',
  549. 'contentid',
  550. 'pagecount',
  551. 'weight',
  552. 'commend',
  553. 'noexpiration',
  554. 'commend_pv',
  555. 'iscount'
  556. ];
  557. foreach ($params as $k => $param) {
  558. if (in_array($k, $intVal, true)) {
  559. $params[$k] = intval($param);
  560. }
  561. }
  562. return $params;
  563. }
  564. /**
  565. * 根据用户年月日算出星座
  566. *
  567. * @param string $dob 出生年月 1990-12-18
  568. *
  569. * @return string
  570. */
  571. function constellation($dob)
  572. {
  573. $dob = date("m-d", strtotime($dob));
  574. list($month, $day) = explode("-", $dob);
  575. $constellation = '';
  576. if (($month == 3 || $month == 4) && ($day > 22 || $day < 21)) {
  577. $constellation = "Aries";
  578. } else if (($month == 4 || $month == 5) && ($day > 22 || $day < 22)) {
  579. $constellation = "Taurus";
  580. } else if (($month == 5 || $month == 6) && ($day > 23 || $day < 22)) {
  581. $constellation = "Gemini";
  582. } else if (($month == 6 || $month == 7) && ($day > 23 || $day < 23)) {
  583. $constellation = "Cancer";
  584. } else if (($month == 7 || $month == 8) && ($day > 24 || $day < 22)) {
  585. $constellation = "Leo";
  586. } else if (($month == 8 || $month == 9) && ($day > 23 || $day < 24)) {
  587. $constellation = "Virgo";
  588. } elseif (($month == 9 || $month == 10) && ($day > 25 || $day < 24)) {
  589. $constellation = "Libra";
  590. } else if (($month == 10 || $month == 11) && ($day > 25 || $day < 23)) {
  591. $constellation = "Scorpio";
  592. } else if (($month == 11 || $month == 12) && ($day > 24 || $day < 23)) {
  593. $constellation = "Sagittarius";
  594. } else if (($month == 12 || $month == 1) && ($day > 24 || $day < 21)) {
  595. $constellation = "Cpricorn";
  596. } else if (($month == 1 || $month == 2) && ($day > 22 || $day < 20)) {
  597. $constellation = "Aquarius";
  598. } else if (($month == 2 || $month == 3) && ($day > 21 || $day < 21)) {
  599. $constellation = "Pisces";
  600. }
  601. return $constellation;
  602. }
  603. /**
  604. * 随机生成短信验证码
  605. * @param int $length 验证码长度
  606. * @return int
  607. */
  608. function generate_code($length = 6)
  609. {
  610. return rand(pow(10, ($length - 1)), pow(10, $length) - 1);
  611. }
  612. /**
  613. * 计算两点地理坐标之间的距离
  614. * @param string $longitude1 起点经度
  615. * @param string $latitude1 起点纬度
  616. * @param string $longitude2 终点经度
  617. * @param string $latitude2 终点纬度
  618. * @param int $unit 单位 1:米 2:公里
  619. * @param int $decimal 精度 保留小数位数
  620. * @return string
  621. */
  622. function getDistance($longitude1, $latitude1, $longitude2, $latitude2, $unit = 2, $decimal = 2)
  623. {
  624. $EARTH_RADIUS = 6370.996; // 地球半径系数
  625. $PI = 3.1415926;
  626. $radLat1 = $latitude1 * $PI / 180.0;
  627. $radLat2 = $latitude2 * $PI / 180.0;
  628. $radLng1 = $longitude1 * $PI / 180.0;
  629. $radLng2 = $longitude2 * $PI / 180.0;
  630. $a = $radLat1 - $radLat2;
  631. $b = $radLng1 - $radLng2;
  632. $distance = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
  633. $distance = $distance * $EARTH_RADIUS * 1000;
  634. if ($unit == 2) {
  635. $distance = $distance / 1000;
  636. }
  637. return round($distance, $decimal);
  638. }
  639. /**
  640. * @param int $month 月份
  641. * @param int $year 年
  642. *
  643. * @return mixed
  644. */
  645. function getMonthBeginToEnd($month, $year = 0)
  646. {
  647. $beginDate = 0;
  648. $endDate = 0;
  649. if ($month = intval($month)) {
  650. if (!$year) {
  651. $year = date('Y', time());
  652. }
  653. $beginDate = strtotime("{$year}-{$month}-01");
  654. $endDate = strtotime(date('Y-m-t', $beginDate));
  655. }
  656. return [
  657. 'beginTime' => $beginDate,
  658. 'endTime' => $endDate
  659. ];
  660. }
  661. /**
  662. * 格式化商品价格
  663. *
  664. * @access public
  665. * @param float $price 商品价格
  666. * @return string
  667. */
  668. function priceFormat($price)
  669. {
  670. return number_format($price, 2, '.', '');
  671. }
  672. /**
  673. * 数组转xml内容
  674. *
  675. * @param array $arr 数组
  676. * @return string
  677. */
  678. function arrayToXml($arr)
  679. {
  680. $xml = '';
  681. foreach ($arr as $key => $value) {
  682. if (is_string($value)) {
  683. $xml .= '<' . $key . '><![CDATA[' . $value . ']]></' . $key . '>';
  684. } else {
  685. $xml .= '<' . $key . '>' . $value . '</' . $key . '>';
  686. }
  687. }
  688. return $xml;
  689. }
  690. //数组转xml
  691. function arrayToWeiXinXml($arr)
  692. {
  693. $xml = '<xml>';
  694. foreach($arr as $key => $value){
  695. if (is_string($value)) {
  696. $xml .= '<' . $key . '><![CDATA[' . $value . ']]></' . $key . '>';
  697. } else {
  698. $xml .= '<' . $key . '>' . $value . '</' . $key . '>';
  699. }
  700. }
  701. $xml .='</xml>';
  702. return $xml;
  703. }
  704. /**
  705. * xml转json格式数据
  706. *
  707. * @param string $xml xml格式文件内容
  708. * @return string
  709. */
  710. function XML2JSON($xml)
  711. {
  712. function normalizeSimpleXML($obj, &$result)
  713. {
  714. $data = $obj;
  715. if (is_object($data)) {
  716. $data = get_object_vars($data);
  717. }
  718. if (is_array($data)) {
  719. foreach ($data as $key => $value) {
  720. $res = null;
  721. normalizeSimpleXML($value, $res);
  722. if (($key == '@attributes') && ($key)) {
  723. $result = $res;
  724. } else {
  725. $result[$key] = $res;
  726. }
  727. }
  728. } else {
  729. $result = $data;
  730. }
  731. }
  732. normalizeSimpleXML(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA), $result);
  733. return json_encode($result, JSON_UNESCAPED_UNICODE);
  734. }
  735. /**
  736. * 分页方法
  737. */
  738. function pageToOffset($page = 1, $pageSize = 10)
  739. {
  740. return [
  741. 'limit' => $pageSize,
  742. 'offset' => ($page - 1) * $pageSize,
  743. ];
  744. }
  745. /**
  746. * PHP截取UTF-8字符串,解决半字符问题。
  747. * 英文、数字(半角)为1字节(8位),中文(全角)为2字节
  748. * 取出的字符串, 当$len小于等于0时, 会返回整个字符串
  749. * @param string $str 源字符串
  750. * @param int $len 左边的子串的长度
  751. */
  752. function utf_substr($str, $len)
  753. {
  754. $new_str = [];
  755. for ($i = 0; $i < $len; $i++) {
  756. $temp_str = substr($str, 0, 1);
  757. if (ord($temp_str) > 127) {
  758. if ($i < $len) {
  759. $new_str[] = substr($str, 0, 3);
  760. $str = substr($str, 3);
  761. }
  762. } else {
  763. $new_str[] = substr($str, 0, 1);
  764. $str = substr($str, 1);
  765. }
  766. }
  767. return join($new_str);
  768. }
  769. function isCardNo($vStr)
  770. {
  771. $vCity = array(
  772. '11', '12', '13', '14', '15', '21', '22',
  773. '23', '31', '32', '33', '34', '35', '36',
  774. '37', '41', '42', '43', '44', '45', '46',
  775. '50', '51', '52', '53', '54', '61', '62',
  776. '63', '64', '65', '71', '81', '82', '91'
  777. );
  778. if (!preg_match('/^([\d]{17}[xX\d]|[\d]{15})$/', $vStr)) return false;
  779. if (!in_array(substr($vStr, 0, 2), $vCity)) return false;
  780. $vStr = preg_replace('/[xX]$/i', 'a', $vStr);
  781. $vLength = strlen($vStr);
  782. if ($vLength == 18) {
  783. $vBirthday = substr($vStr, 6, 4) . '-' . substr($vStr, 10, 2) . '-' . substr($vStr, 12, 2);
  784. } else {
  785. $vBirthday = '19' . substr($vStr, 6, 2) . '-' . substr($vStr, 8, 2) . '-' . substr($vStr, 10, 2);
  786. }
  787. if (date('Y-m-d', strtotime($vBirthday)) != $vBirthday) return false;
  788. if ($vLength == 18) {
  789. $vSum = 0;
  790. for ($i = 17; $i >= 0; $i--) {
  791. $vSubStr = substr($vStr, 17 - $i, 1);
  792. $vSum += (pow(2, $i) % 11) * (($vSubStr == 'a') ? 10 : intval($vSubStr, 11));
  793. }
  794. if ($vSum % 11 != 1) return false;
  795. }
  796. return true;
  797. }
  798. /**
  799. * try_catch 统一写入日志方法
  800. * @param object $logger Factory::logs
  801. * @param $exception 捕获的异常内容
  802. */
  803. function catchError($logger, $exception)
  804. {
  805. $error = '错误类型:' . get_class($exception) . PHP_EOL;
  806. $error .= '错误代码:' . $exception->getCode() . PHP_EOL;
  807. $error .= '错误信息:' . $exception->getMessage() . PHP_EOL;
  808. $error .= '错误堆栈:' . $exception->getTraceAsString() . PHP_EOL;
  809. $logger && $logger->log($error, 'error');
  810. }
  811. /**
  812. * 资金元单位转化为分单位
  813. * @param float 元
  814. * @return int 分
  815. */
  816. function yuanToFen($yuan)
  817. {
  818. $fen = strval($yuan * 100);
  819. return intval($fen);
  820. }
  821. /**
  822. * 资金分单位转化为元单位
  823. * @param int 分
  824. * @return float 元
  825. */
  826. function fenToYuan($fen)
  827. {
  828. $fen = $fen / 100;
  829. return $fen;
  830. }
  831. /**
  832. * 千克转为克
  833. * @param string|float
  834. * @return int
  835. */
  836. function kgTog($kg)
  837. {
  838. $g = strval($kg * 1000);
  839. return $g = intval($g);
  840. }
  841. /**
  842. * 克转为千克
  843. * @param string|float
  844. * @return int
  845. */
  846. function gToKg($kg)
  847. {
  848. $kg = $kg / 1000;
  849. return $kg;
  850. }
  851. /**
  852. * 元/千克 转为 分/克 并保留8位有效数字
  853. * @param string|float
  854. * @return int
  855. */
  856. function kgYuanTogFenDanWei($KgYuan)
  857. {
  858. $gFen = $KgYuan / 10;
  859. return $gFen;
  860. }
  861. function floatDiv($param)
  862. {
  863. return $param / 100000000;
  864. }
  865. function floatMul($param)
  866. {
  867. return $param * 100000000;
  868. }
  869. /**
  870. * 分/克 转为 元/千克
  871. * @param string|float
  872. * @return int
  873. */
  874. function gFenToKgYuanDanWei($gFen)
  875. {
  876. $kgYuan = $gFen * 10;
  877. return $kgYuan;
  878. }
  879. /**
  880. * 获取当前的时间(毫秒)
  881. * @return float
  882. */
  883. function getMillisecond()
  884. {
  885. list($t1, $t2) = explode(' ', microtime());
  886. return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
  887. }
  888. /**
  889. * 多维数组转树状结构
  890. *
  891. * @param $tree
  892. * @param int $rootId
  893. * @return array
  894. */
  895. function arr2tree($tree, $rootId = 0)
  896. {
  897. $return = [];
  898. foreach ($tree as $leaf) {
  899. if ($leaf['pid'] == $rootId) {
  900. foreach ($tree as $subleaf) {
  901. if ($subleaf['pid'] == $leaf['id']) {
  902. $leaf['children'] = arr2tree($tree, $leaf['id']);
  903. break;
  904. }
  905. }
  906. $return[] = $leaf;
  907. }
  908. }
  909. return $return;
  910. }
  911. /**
  912. * <生成订单号>
  913. * 规则说明: 来源(pc/ios/android)1位 + 订单类型标示(海淘/门票)1位 + 时间戳转日期(20171107)8位 + 用户id(2位) + 毫秒时间提取(4位)
  914. * @param $orderFrom
  915. * @param $orderTypeId
  916. * @param $userId
  917. * @return int
  918. */
  919. function createOrderSn($orderFrom, $orderTypeId, $userId)
  920. {
  921. $no = $orderFrom . $orderTypeId . date('Ymd') . substr(strval($userId + 100), -2) . substr(microtime(), 2, 4) . sprintf('%02d', rand(1000, 9999));
  922. return $no;
  923. }
  924. /**
  925. * 按照日期生成流水号
  926. * @param string $maxNo 当天最后一条数据编号
  927. */
  928. function createSerialNumberByDate($maxNo = '',$dateLength = 8, $lenght = 4)
  929. {
  930. $number = 0;
  931. if( !empty($maxNo) ){
  932. $todayLastNo = explode('-',$maxNo);
  933. $number = intval($todayLastNo[1]);
  934. }
  935. $number = $number+1;
  936. switch ($dateLength){
  937. case 12: // 根据年月日时分生成流水号
  938. $date = date('YmdHi',time());
  939. break;
  940. case 14: // 根据年月日时分秒生成流水号
  941. $date = date('YmdHis',time());
  942. break;
  943. default: // 根据年月日生成流水号
  944. $date = date('Ymd',time());
  945. }
  946. return $date.'-'.str_pad($number,$lenght,'0',STR_PAD_LEFT);
  947. }
  948. /**
  949. * 生成编码
  950. * @param $prefix 编码前缀 例如:采购入库单 CGRK
  951. * @param $id 自动id
  952. * @param int $length 编码长度
  953. * @return string
  954. */
  955. function createCode($prefix, $id, $length = 6)
  956. {
  957. $idLength = strlen((string)$id);
  958. $leaveLength = $length - $idLength;
  959. $zeroStr = "";
  960. if ($leaveLength > 0) {
  961. $zeroStr = str_repeat('0', $leaveLength);
  962. }
  963. return strtoupper($prefix) . $zeroStr . $id;
  964. }
  965. /**
  966. * 随机生成16位字符串
  967. * @return string 生成的字符串
  968. */
  969. function getRandomStr($lenght = 16)
  970. {
  971. $str = "";
  972. $str_pol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
  973. $max = strlen($str_pol) - 1;
  974. for ($i = 0; $i < $lenght; $i++) {
  975. $str .= $str_pol[mt_rand(0, $max)];
  976. }
  977. return $str;
  978. }
  979. /*
  980. * uuid 唯一序列码
  981. */
  982. function uuid($prefix = '')
  983. {
  984. $chars = md5(uniqid(mt_rand(), true));
  985. $uuid = substr($chars,0,8) . '-';
  986. $uuid .= substr($chars,8,4) . '-';
  987. $uuid .= substr($chars,12,4) . '-';
  988. $uuid .= substr($chars,16,4) . '-';
  989. $uuid .= substr($chars,20,12);
  990. return $prefix . $uuid;
  991. }
  992. /**
  993. * 获取 当天,昨天,本周,本月,本年时间戳
  994. */
  995. function gettimestamp($name = 'today',$param = ''){
  996. switch ($name){
  997. case 'today'://今天
  998. $timeamp['start'] = strtotime(date('Y-m-d'));
  999. $timeamp['end'] = strtotime(date('Y-m-d',strtotime('+1 day')));
  1000. break;
  1001. case 'yesterday'://昨天
  1002. $timeamp['start'] = strtotime(date('Y-m-d',strtotime('-1 day')));
  1003. $timeamp['end'] = strtotime(date('Y-m-d'));
  1004. break;
  1005. case 'beforyesterday'://前天
  1006. $timeamp['start'] = strtotime(date('Y-m-d',strtotime('-2 day')));
  1007. $timeamp['end'] = strtotime(date('Y-m-d',strtotime('-1 day')));
  1008. break;
  1009. case 'beforweek'://本周
  1010. $timeamp['start'] = strtotime(date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-date("w")+1,date("Y"))));
  1011. $timeamp['end'] = strtotime(date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y"))));
  1012. break;
  1013. case 'nowmonth'://本月
  1014. $timeamp['start'] = strtotime(date('Y-m-01'));
  1015. $timeamp['end'] = strtotime(date('Y-m-d',strtotime('+1 day')));
  1016. break;
  1017. case 'permonth'://上月
  1018. $timeamp['start'] = strtotime(date('Y-m-01',strtotime('-1 month')));
  1019. $timeamp['end'] = strtotime(date('Y-m-01'));
  1020. break;
  1021. case 'preweek'://上周 注意我们是从周一开始算
  1022. $timeamp['start'] = strtotime(date('Y-m-d',strtotime('-2 week Monday')));
  1023. $timeamp['end'] = strtotime(date('Y-m-d',strtotime('-1 week Monday +1 day')));
  1024. break;
  1025. case 'nowweek'://本周
  1026. $timeamp['start'] = strtotime(date('Y-m-d',strtotime('-1 week Monday')));
  1027. $timeamp['end'] = strtotime(date('Y-m-d',strtotime('+1 day')));
  1028. break;
  1029. case 'preday'://近三个月
  1030. // $timeamp['start'] = strtotime(date('Y-m-d'),strtotime($param.' day'));
  1031. $timeamp['start'] = strtotime("-0 year -3 month -0 day");
  1032. $timeamp['end'] = strtotime(date('Y-m-d'));
  1033. break;
  1034. case 'nextday'://30
  1035. $timeamp['start'] = strtotime(date('Y-m-d'));
  1036. $timeamp['end'] = strtotime(date('Y-m-d'),strtotime($param.' day'));
  1037. break;
  1038. case 'preyear'://去年
  1039. $timeamp['start'] = strtotime(date('Y-01-01',strtotime('-1 year')));
  1040. $timeamp['end'] = strtotime(date('Y-12-31',strtotime('-1 year')));
  1041. break;
  1042. case 'nowyear'://今年
  1043. $timeamp['start'] = strtotime(date('Y-01-01'));
  1044. $timeamp['end'] = strtotime(date('Y-m-d',strtotime('+1 day')));
  1045. break;
  1046. case 'quarter'://季度
  1047. $quarter = empty($param) ? ceil((date('n'))/3) : $param;//获取当前季度
  1048. $timeamp['start'] = mktime(0, 0, 0,$quarter*3-2,1,date('Y'));
  1049. $timeamp['end'] = mktime(0, 0, 0,$quarter*3+1,1,date('Y'));
  1050. // $timeamp['end'] = mktime(23,59,59,$quarter*3,date('t',mktime(0, 0 , 0,$quarter*3,1,date("Y"))),date('Y'));
  1051. break;
  1052. default:
  1053. $timeamp['start'] = strtotime(date('Y-m-d'));
  1054. $timeamp['end'] = strtotime(date('Y-m-d',strtotime('+1 day')));
  1055. break;
  1056. }
  1057. return $timeamp;
  1058. }