1 <?php
2 3 4 5 6 7
8
9 namespace Cross\Core;
10
11 use Cross\Http\Request;
12 use DOMDocument;
13
14 15 16 17 18
19 class Helper
20 {
21 22 23 24 25 26 27 28
29 public static function subStr($str, $len, $enc = 'utf8')
30 {
31 if (self::strLen($str) > $len) {
32 return mb_substr($str, 0, $len, $enc) . '...';
33 } else {
34 return $str;
35 }
36 }
37
38 39 40 41 42 43 44 45
46 public static function subStrHTML($str, $len, $enc = 'utf8')
47 {
48 $str = self::subStr($str, $len, $enc);
49 return self::formatHTMLString($str);
50 }
51
52 53 54 55 56 57 58
59 public static function formatHTMLString($str, $removing_doctype = true)
60 {
61 $DOCUMENT = new DOMDocument();
62 @$DOCUMENT->loadHTML(mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8'));
63 $content = $DOCUMENT->saveHTML($DOCUMENT->documentElement);
64 if ($removing_doctype) {
65 return preg_replace('~<(?:!DOCTYPE|/?(?:html|body))[^>]*>\s*~i', '', $content);
66 }
67
68 return $content;
69 }
70
71 72 73 74 75 76 77
78 public static function strLen($str, $enc = 'gb2312')
79 {
80 return min(array(mb_strlen($str, $enc), mb_strlen($str, 'utf-8')));
81 }
82
83 84 85 86 87 88 89
90 static function stringToArray($str, $charset = 'utf-8')
91 {
92 if ($charset != 'utf-8') {
93 $str = iconv($charset, 'utf-8', $str);
94 }
95
96 $result = array();
97 for ($i = 0, $str_len = mb_strlen($str, 'utf-8'); $i < $str_len; $i++) {
98 $result[] = mb_substr($str, $i, 1, 'utf-8');
99 }
100
101 return $result;
102 }
103
104 105 106 107 108 109
110 static function md10($str = '')
111 {
112 return substr(md5($str), 10, 10);
113 }
114
115 116 117 118 119 120
121 static function getExt($file)
122 {
123 return pathinfo($file, PATHINFO_EXTENSION);
124 }
125
126 127 128 129 130 131 132 133
134 static function createFolders($path, $mode = 0755, $recursive = true)
135 {
136 if (!is_dir($path)) {
137 return mkdir($path, $mode, $recursive);
138 }
139
140 return true;
141 }
142
143 144 145 146 147 148 149 150
151 static function mkfile($file_name, $mode = 0644, $dir_mode = 0755)
152 {
153 if (!file_exists($file_name)) {
154 $file_path = dirname($file_name);
155 $createFolder = self::createFolders($file_path, $dir_mode, true);
156 if ($createFolder) {
157 $fp = fopen($file_name, 'w+');
158 if ($fp) {
159 fclose($fp);
160 chmod($file_name, $mode);
161 return true;
162 }
163 }
164
165 return false;
166 }
167 return true;
168 }
169
170 171 172 173 174 175 176
177 static function validEmail($email, $add_valid_expr = "/^[a-zA-Z0-9]([\w\-\.]?)+/")
178 {
179 if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
180
181 if ($add_valid_expr) {
182 list($valid_string,) = explode('@', $email);
183 if (!preg_match($add_valid_expr, $valid_string)) {
184 return false;
185 }
186 }
187
188 return true;
189 }
190
191 return false;
192 }
193
194 195 196 197 198 199 200
201 static function random($length, $numeric = 0)
202 {
203 $seed = md5(print_r($_SERVER, 1) . microtime(true));
204 if ($numeric) {
205 $seed = str_replace('0', '', base_convert($seed, 16, 10)) . '0123456789';
206 } else {
207 $seed = base_convert($seed, 16, 35) . 'zZz' . strtoupper($seed);
208 }
209
210 $hash = '';
211 $max = strlen($seed) - 1;
212 for ($i = 0; $i < $length; $i++) {
213 $hash .= $seed[mt_rand(0, $max)];
214 }
215
216 return $hash;
217 }
218
219 220 221 222 223 224
225 static function parseAt($str)
226 {
227 preg_match_all("/@([^@^\\s^:]{1,})([\\s\\:\\,\\;]{0,1})/", $str, $result);
228 return $result;
229 }
230
231 232 233 234 235 236 237
238 static function stripSelectedTags($str, $disallowable = '<script><iframe><style><link>')
239 {
240 $disallowable = trim(str_replace(array('>', '<'), array('', '|'), $disallowable), '|');
241 $str = str_replace(array('<', '>'), array('<', '>'), $str);
242 $str = preg_replace("~<({$disallowable})[^>]*>(.*?<\s*\/(\\1)[^>]*>)?~is", '$2', $str);
243
244 return $str;
245 }
246
247 248 249 250 251 252
253 static function convertTags($str)
254 {
255 return str_replace(array('<', '>', "'", '"'), array('<', '>', ''', '"'), $str);
256 }
257
258 259 260 261 262 263 264 265 266
267 static function authCode($string, $operation = 'DECODE', $key = 'crossphp', $expiry = 0)
268 {
269 $c_key_length = 4;
270 $key = md5($key);
271
272 $key_a = md5(substr($key, 0, 16));
273 $key_b = md5(substr($key, 16, 16));
274 $key_c = $c_key_length ? ($operation == 'DECODE' ? substr($string, 0, $c_key_length) :
275 substr(md5(microtime()), -$c_key_length)) : '';
276
277 $crypt_key = $key_a . md5($key_a . $key_c);
278 $key_length = strlen($crypt_key);
279
280 $string = $operation == 'DECODE' ?
281 base64_decode(substr($string, $c_key_length)) :
282 sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $key_b), 0, 16) . $string;
283
284 $result = array();
285 $box = range(0, 255);
286 $string_length = strlen($string);
287
288 $rnd_key = array();
289 for ($i = 0; $i <= 255; $i++) {
290 $rnd_key[$i] = $crypt_key[$i % $key_length];
291 }
292 $rnd_key = array_map('ord', $rnd_key);
293
294 for ($j = $i = 0; $i < 256; $i++) {
295 $j = ($j + $box[$i] + $rnd_key[$i]) % 256;
296 $tmp = $box[$i];
297 $box[$i] = $box[$j];
298 $box[$j] = $tmp;
299 }
300
301 $p1 = $p2 = array();
302 for ($a = $j = $i = 0; $i < $string_length; $i++) {
303 $a = ($a + 1) % 256;
304 $j = ($j + $box[$a]) % 256;
305 $tmp = $box[$a];
306 $box[$a] = $box[$j];
307 $box[$j] = $tmp;
308 $p1[] = $string[$i];
309 $p2[] = $box[($box[$a] + $box[$j]) % 256];
310 }
311
312 if (!empty($p1)) {
313 $p1 = array_map('ord', $p1);
314 foreach ($p1 as $k => $pv) {
315 $result[] = $pv ^ $p2[$k];
316 }
317
318 unset($p1, $p2, $box, $tmp, $rnd_key);
319 $result = implode('', array_map('chr', $result));
320 }
321
322 if ($operation == 'DECODE') {
323 if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) &&
324 substr($result, 10, 16) == substr(md5(substr($result, 26) . $key_b), 0, 16)
325 ) {
326 return substr($result, 26);
327 } else {
328 return '';
329 }
330 } else {
331 return $key_c . str_replace('=', '', base64_encode($result));
332 }
333 }
334
335 336 337 338 339 340 341 342
343 static function encodeParams($str, $key, $operation = 'encode')
344 {
345 $result = '';
346 static $key_cache;
347 if (!isset($key_cache[$key])) {
348 $key_cache[$key] = md5($key);
349 }
350
351 $key = $key_cache[$key];
352 if ($operation == 'encode') {
353 $str = (string)$str;
354 } else {
355
356
357 $str_head = substr($str, 0, 5);
358 $str = substr($str, 5);
359 if ($str_head != substr(md5($str . $key), 9, 5)) {
360 return $result;
361 }
362
363 $str = pack('H*', $str);
364 }
365
366 if (!$str) {
367 return $result;
368 }
369
370 for ($str_len = strlen($str), $i = 0; $i < $str_len; $i++) {
371 $result .= chr(ord($str[$i]) ^ ord($key[$i % 32]));
372 }
373
374 if ($operation == 'encode') {
375 $result = bin2hex($result);
376 $result = substr(md5($result . $key), 9, 5) . $result;
377 }
378
379 return $result;
380 }
381
382 383 384 385 386 387 388 389 390 391 392
393 static function getPath($id, $path_name = '')
394 {
395 $id = (string)abs($id);
396 $id = str_pad($id, 9, '0', STR_PAD_LEFT);
397 $dir1 = substr($id, 0, 3);
398 $dir2 = substr($id, 3, 2);
399 $dir3 = substr($id, 5, 2);
400
401 return $path_name . '/' . $dir1 . '/' . $dir2 . '/' . $dir3 . '/' . substr($id, -2) . '/';
402 }
403
404 405 406 407 408 409 410 411 412 413 414
415 static function curlRequest($url, $vars = array(), $method = 'POST', $timeout = 10, $CA = false, $cacert = '')
416 {
417 $method = strtoupper($method);
418 $SSL = substr($url, 0, 8) == "https://" ? true : false;
419 if ($method == 'GET' && !empty($vars)) {
420 $params = is_array($vars) ? http_build_query($vars) : $vars;
421 $url = rtrim($url, '?');
422 if (false === strpos($url . $params, '?')) {
423 $url = $url . '?' . ltrim($params, '&');
424 } else {
425 $url = $url . $params;
426 }
427 }
428
429 $ch = curl_init();
430 curl_setopt($ch, CURLOPT_URL, $url);
431 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
432 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout - 3);
433 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
434 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
435 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
436 curl_setopt($ch, CURLOPT_HTTPHEADER, array("X-HTTP-Method-Override: {$method}"));
437
438 if ($SSL && $CA && $cacert) {
439 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
440 curl_setopt($ch, CURLOPT_CAINFO, $cacert);
441 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
442 } else if ($SSL && !$CA) {
443 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
444 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
445 }
446
447 if ($method == 'POST' || $method == 'PUT') {
448 curl_setopt($ch, CURLOPT_POST, 1);
449 curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);
450 curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
451 }
452 $result = curl_exec($ch);
453 $error_no = curl_errno($ch);
454 if (!$error_no) {
455 $result = trim($result);
456 } else {
457 $result = $error_no;
458 }
459
460 curl_close($ch);
461 return $result;
462 }
463
464 465 466 467 468 469 470
471 static function escape($str, $quote_style = ENT_COMPAT)
472 {
473 return htmlspecialchars($str, $quote_style);
474 }
475
476 477 478 479 480 481 482 483 484 485 486 487 488
489 static function arrayRandomRate(array $array)
490 {
491 asort($array);
492 $max = array_sum($array);
493 foreach ($array as $a_key => $a_value) {
494 $rand = mt_rand(0, $max);
495
496 if ($rand <= $a_value) {
497 return $a_key;
498 } else {
499 $max -= $a_value;
500 }
501 }
502
503 return false;
504 }
505
506 507 508 509 510 511
512 static function isChinese($string)
513 {
514 if (preg_match("/^[\\x{4e00}-\\x{9fa5}]+$/u", $string)) {
515 return true;
516 }
517
518 return false;
519 }
520
521 522 523 524 525 526
527 static function isMobile($mobile)
528 {
529 if (preg_match("/^1[3456789]\\d{9}$/", $mobile)) {
530 return true;
531 }
532
533 return false;
534 }
535
536 537 538 539 540 541 542
543 static function checkIDCard($id_card, $just_check_length = true)
544 {
545
546 $length_validate = preg_match('/^([\d]{17}[xX\d]|[\d]{15})$/', $id_card) === 1;
547 if ($just_check_length) {
548 return $length_validate;
549 }
550
551 if (!$length_validate) {
552 return false;
553 }
554
555 $city_code = array(
556 11 => true, 12 => true, 13 => true, 14 => true, 15 => true,
557 21 => true, 22 => true, 23 => true,
558 31 => true, 32 => true, 33 => true, 34 => true, 35 => true, 36 => true, 37 => true,
559 41 => true, 42 => true, 43 => true, 44 => true, 45 => true, 46 => true,
560 50 => true, 51 => true, 52 => true, 53 => true, 54 => true,
561 61 => true, 62 => true, 63 => true, 64 => true, 65 => true,
562 71 => true,
563 81 => true, 82 => true,
564 91 => true,
565 );
566
567
568 if (!isset($city_code[$id_card[0] . $id_card[1]])) {
569 return false;
570 }
571
572
573 $make_verify_bit = function ($id_card) {
574 if (strlen($id_card) != 17) {
575 return null;
576 }
577
578 $factor = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
579
580 $verify_number_list = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
581 $checksum = 0;
582 for ($i = 0; $i < 17; $i++) {
583 $checksum += $id_card[$i] * $factor[$i];
584 }
585
586 $mod = $checksum % 11;
587 $verify_number = $verify_number_list[$mod];
588 return $verify_number;
589 };
590
591 $id_card_length = strlen($id_card);
592 if ($id_card_length == 15) {
593
594 if (array_search(substr($id_card, 12, 3), array('996', '997', '998', '999')) !== false) {
595 $id_card = substr($id_card, 0, 6) . '18' . substr($id_card, 6, 9);
596 } else {
597 $id_card = substr($id_card, 0, 6) . '19' . substr($id_card, 6, 9);
598 }
599
600 $id_card .= $make_verify_bit($id_card);
601 } else {
602
603 if (strcasecmp($id_card[17], $make_verify_bit(substr($id_card, 0, 17))) != 0) {
604 return false;
605 }
606 }
607
608
609 $birth_day = substr($id_card, 6, 8);
610 $d = new \DateTime($birth_day);
611 if ($d->format('Y') > date('Y') || $d->format('m') > 12 || $d->format('d') > 31) {
612 return false;
613 }
614
615 return true;
616 }
617
618 619 620 621 622 623 624 625 626
627 static function encrypt($data, $op = 'DECODE', $key = '!@#%c*r&o*s^s%p$h~p&', $method = 'AES-256-CBC')
628 {
629 $encrypt_key = md5($key);
630 if ($op == 'ENCODE') {
631 $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($method));
632 $encrypted = openssl_encrypt($data, $method, $encrypt_key, 0, $iv);
633 $result = str_replace(array('=', '/', '+'), array('', '-', '_'), base64_encode($encrypted . '::' . $iv));
634 } else {
635 $data = base64_decode(str_replace(array('-', '_'), array('/', '+'), $data));
636 list($encrypted, $iv) = explode('::', $data);
637 $result = openssl_decrypt($encrypted, $method, $encrypt_key, 0, $iv);
638 }
639
640 return $result;
641 }
642
643 644 645 646 647
648 static function getIp()
649 {
650 return Request::getInstance()->getClientIPAddress();
651 }
652
653 654 655 656 657 658
659 static function getLongIp($ip = '')
660 {
661 if ($ip == '') {
662 $ip = self::getIp();
663 }
664
665 return sprintf("%u", ip2long($ip));
666 }
667
668 669 670 671 672 673 674 675 676
677 static function ftime($time, $format = 'Y-m-d H:i:s', $start_time = 0, $suffix = '前')
678 {
679 if ($start_time == 0) {
680 $start_time = time();
681 }
682
683 $t = $start_time - $time;
684 if ($t < 63072000) {
685 $f = array(
686 '31536000' => '年',
687 '2592000' => '个月',
688 '604800' => '星期',
689 '86400' => '天',
690 '3600' => '小时',
691 '60' => '分钟',
692 '1' => '秒'
693 );
694
695 foreach ($f as $k => $v) {
696 if (0 != $c = floor($t / (int)$k)) {
697 return $c . $v . $suffix;
698 }
699 }
700 }
701
702 return date($format, $time);
703 }
704
705 706 707 708 709 710
711 static function convert($size)
712 {
713 $unit = array('b', 'kb', 'mb', 'gb', 'tb', 'pb');
714 $s = floor(log($size, 1024));
715 $i = (int)$s;
716
717 if (isset($unit[$i])) {
718 return sprintf('%.2f ' . $unit[$i], $size / pow(1024, $s));
719 }
720
721 return $size . ' ' . $unit[0];
722 }
723 }
724