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