Str.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. <?php
  2. /* file: 字符串处理类
  3. Created by wanghong<1204772286@qq.com>
  4. Date: 2021-02-22 */
  5. namespace utils;
  6. class Str{
  7. protected static $snakeCache = [];
  8. protected static $camelCache = [];
  9. protected static $studlyCache = [];
  10. /**
  11. * 检查字符串中是否包含某些字符串
  12. * @param string $haystack
  13. * @param string|array $needles
  14. * @return bool
  15. */
  16. public static function contains($haystack, $needles)
  17. {
  18. foreach ((array) $needles as $needle) {
  19. if ($needle != '' && mb_strpos($haystack, $needle) !== false) {
  20. return true;
  21. }
  22. }
  23. return false;
  24. }
  25. /**
  26. * 检查字符串是否以某些字符串结尾
  27. *
  28. * @param string $haystack
  29. * @param string|array $needles
  30. * @return bool
  31. */
  32. public static function endsWith($haystack, $needles)
  33. {
  34. foreach ((array) $needles as $needle) {
  35. if ((string) $needle === static::substr($haystack, -static::length($needle))) {
  36. return true;
  37. }
  38. }
  39. return false;
  40. }
  41. /**
  42. * 检查字符串是否以某些字符串开头
  43. *
  44. * @param string $haystack
  45. * @param string|array $needles
  46. * @return bool
  47. */
  48. public static function startsWith($haystack, $needles)
  49. {
  50. foreach ((array) $needles as $needle) {
  51. if ($needle != '' && mb_strpos($haystack, $needle) === 0) {
  52. return true;
  53. }
  54. }
  55. return false;
  56. }
  57. /**
  58. * 获取指定长度的随机字母数字组合的字符串
  59. *
  60. * @param int $length
  61. * @return string
  62. */
  63. public static function random($length = 16)
  64. {
  65. $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  66. return static::substr(str_shuffle(str_repeat($pool, $length)), 0, $length);
  67. }
  68. /**
  69. * 字符串转小写
  70. *
  71. * @param string $value
  72. * @return string
  73. */
  74. public static function lower($value)
  75. {
  76. return mb_strtolower($value, 'UTF-8');
  77. }
  78. /**
  79. * 字符串转大写
  80. *
  81. * @param string $value
  82. * @return string
  83. */
  84. public static function upper($value)
  85. {
  86. return mb_strtoupper($value, 'UTF-8');
  87. }
  88. /**
  89. * 获取字符串的长度
  90. *
  91. * @param string $value
  92. * @return int
  93. */
  94. public static function length($value)
  95. {
  96. return mb_strlen($value);
  97. }
  98. /**
  99. * 截取字符串
  100. *
  101. * @param string $string
  102. * @param int $start
  103. * @param int|null $length
  104. * @return string
  105. */
  106. public static function substr($string, $start, $length = null)
  107. {
  108. return mb_substr($string, $start, $length, 'UTF-8');
  109. }
  110. /**
  111. * 驼峰转下划线
  112. *
  113. * @param string $value
  114. * @param string $delimiter
  115. * @return string
  116. */
  117. public static function snake($value, $delimiter = '_')
  118. {
  119. $key = $value;
  120. if (isset(static::$snakeCache[$key][$delimiter])) {
  121. return static::$snakeCache[$key][$delimiter];
  122. }
  123. if (!ctype_lower($value)) {
  124. $value = preg_replace('/\s+/u', '', $value);
  125. $value = static::lower(preg_replace('/(.)(?=[A-Z])/u', '$1' . $delimiter, $value));
  126. }
  127. return static::$snakeCache[$key][$delimiter] = $value;
  128. }
  129. /**
  130. * 下划线转驼峰(首字母小写)
  131. *
  132. * @param string $value
  133. * @return string
  134. */
  135. public static function camel($value)
  136. {
  137. if (isset(static::$camelCache[$value])) {
  138. return static::$camelCache[$value];
  139. }
  140. return static::$camelCache[$value] = lcfirst(static::studly($value));
  141. }
  142. /**
  143. * 下划线转驼峰(首字母大写)
  144. *
  145. * @param string $value
  146. * @return string
  147. */
  148. public static function studly($value)
  149. {
  150. $key = $value;
  151. if (isset(static::$studlyCache[$key])) {
  152. return static::$studlyCache[$key];
  153. }
  154. $value = ucwords(str_replace(['-', '_'], ' ', $value));
  155. return static::$studlyCache[$key] = str_replace(' ', '', $value);
  156. }
  157. /**
  158. * 转为首字母大写的标题格式
  159. *
  160. * @param string $value
  161. * @return string
  162. */
  163. public static function title($value)
  164. {
  165. return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');
  166. }
  167. /*
  168. 在数组中取想要的值
  169. $array -array 被取值的数组
  170. $field -string 所取的字段
  171. $is_str -boolean 返回字符串(默认)或数组
  172. return string
  173. */
  174. public static function array_to_string($array,$field,$is_str=true){
  175. $arr=[];
  176. foreach($array as $k => $v){
  177. if($v[$field]){
  178. $arr[]=$v[$field];
  179. }
  180. }
  181. //$idArr = array_unique($idArr);
  182. if($is_str){
  183. return implode(',',$arr);
  184. }else{
  185. return $arr;
  186. }
  187. }
  188. /*
  189. 密码生成规则
  190. $password -string 要转化的字符串
  191. return string
  192. */
  193. public static function password_hash_tp($password)
  194. {
  195. return hash("md5", trim($password));
  196. }
  197. /*
  198. 字符串截取函数
  199. $str -string 被截取的字符串
  200. $start -int 起始位置
  201. $length -int 截取长度
  202. $charset -string 编码
  203. $suffix -boolean 在$str的结尾拼接省略号(默认true)
  204. return string
  205. */
  206. public static function msubstr($str, $start, $length, $charset = "utf-8", $suffix = true)
  207. {
  208. if (strlen($str) / 3 > $length) {
  209. if (function_exists("mb_substr")) {
  210. if ($suffix == false) {
  211. return mb_substr($str, $start, $length, $charset) . '&nbsp;...';
  212. } else {
  213. return mb_substr($str, $start, $length, $charset);
  214. }
  215. } elseif (function_exists('iconv_substr')) {
  216. if ($suffix == false) {
  217. return iconv_substr($str, $start, $length, $charset) . '&nbsp;...';
  218. } else {
  219. return iconv_substr($str, $start, $length, $charset);
  220. }
  221. }
  222. $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
  223. $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
  224. $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
  225. $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
  226. preg_match_all($re[$charset], $str, $match);
  227. $slice = join("", array_slice($match[0], $start, $length));
  228. if ($suffix) {
  229. return $slice;
  230. } else {
  231. return $slice;
  232. }
  233. }
  234. return $str;
  235. }
  236. /*
  237. 获取指定长度的随机字符串
  238. $length 取值长度
  239. return string
  240. */
  241. public static function get_rand_char($length)
  242. {
  243. $str = null;
  244. $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
  245. $max = strlen($strPol) - 1;
  246. for ($i = 0; $i < $length; $i++) {
  247. $str .= $strPol[rand(0, $max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数
  248. }
  249. return $str;
  250. }
  251. /*
  252. 隐藏电话中间四位数
  253. $num -string 电话号码
  254. return string
  255. */
  256. public static function hide_phone($num)
  257. {
  258. return substr($num, 0, 3) . '****' . substr($num, 7);
  259. }
  260. /*
  261. 匹配特殊字符
  262. $word -string 匹配特殊字符
  263. */
  264. public static function match_special_str($word)
  265. {
  266. if (preg_match("/[\'.,:;*?~`!@#$%^&+=<>{}]|\]|\[|\/|\\\|\"|\|/", $word)) {
  267. //不允许特殊字符
  268. return true;
  269. } else {
  270. return false;
  271. }
  272. }
  273. // +----------------------------------------------------------------------
  274. // 数据加密处理
  275. // +----------------------------------------------------------------------
  276. //id加密
  277. public static function encryption($str)
  278. {
  279. $hash = config('hashids');
  280. return hashids($hash['length'], $hash['salt'])->encode($str);
  281. }
  282. //id解密
  283. public static function decrypt($str)
  284. {
  285. $hash = config('hashids');
  286. return hashids($hash['length'], $hash['salt'])->decode($str);
  287. }
  288. //token加密
  289. public static function encryptionToken($id)
  290. {
  291. $str = encryption($id);
  292. $time = md5(strtotime(date('Y-m-d')));
  293. $str = base64_encode($str . '-' . $time);
  294. return $str;
  295. }
  296. //token解密
  297. public static function decryptToken($str)
  298. {
  299. $str = base64_decode($str);
  300. $arr = explode('-', $str);
  301. $time = md5(strtotime(date('Y-m-d')));
  302. if ($arr[1] != $time) {
  303. return false;
  304. }
  305. return decrypt($arr[0]);
  306. }
  307. /* @param string $string 原文或者密文
  308. * @param string $operation 操作(ENCODE | DECODE), 默认为 DECODE
  309. * @param string $key 密钥
  310. * @param int $expiry 密文有效期, 加密时候有效, 单位 秒,0 为永久有效
  311. * @return string 处理后的 原文或者 经过 base64_encode 处理后的密文
  312. *
  313. * @example
  314. *
  315. * $a = authcode('abc', 'ENCODE', 'key');
  316. * $b = authcode($a, 'DECODE', 'key'); // $b(abc)
  317. *
  318. * $a = authcode('abc', 'ENCODE', 'key', 3600);
  319. * $b = authcode('abc', 'DECODE', 'key'); // 在一个小时内,$b(abc),否则 $b 为空
  320. */
  321. public static function authcode($string, $operation = 'DECODE', $key = '', $expiry = 3600) {
  322. $ckey_length = 4;
  323. // 随机密钥长度 取值 0-32;
  324. // 加入随机密钥,可以令密文无任何规律,即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度。
  325. // 取值越大,密文变动规律越大,密文变化 = 16 的 $ckey_length 次方
  326. // 当此值为 0 时,则不产生随机密钥
  327. $key = md5($key ? $key : 'default_key'); //这里可以填写默认key值
  328. $keya = md5(substr($key, 0, 16));
  329. $keyb = md5(substr($key, 16, 16));
  330. $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
  331. $cryptkey = $keya.md5($keya.$keyc);
  332. $key_length = strlen($cryptkey);
  333. $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
  334. $string_length = strlen($string);
  335. $result = '';
  336. $box = range(0, 255);
  337. $rndkey = array();
  338. for($i = 0; $i <= 255; $i++) {
  339. $rndkey[$i] = ord($cryptkey[$i % $key_length]);
  340. }
  341. for($j = $i = 0; $i < 256; $i++) {
  342. $j = ($j + $box[$i] + $rndkey[$i]) % 256;
  343. $tmp = $box[$i];
  344. $box[$i] = $box[$j];
  345. $box[$j] = $tmp;
  346. }
  347. for($a = $j = $i = 0; $i < $string_length; $i++) {
  348. $a = ($a + 1) % 256;
  349. $j = ($j + $box[$a]) % 256;
  350. $tmp = $box[$a];
  351. $box[$a] = $box[$j];
  352. $box[$j] = $tmp;
  353. $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
  354. }
  355. if($operation == 'DECODE') {
  356. if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
  357. return substr($result, 26);
  358. } else {
  359. return '';
  360. }
  361. } else {
  362. return $keyc.str_replace('=', '', base64_encode($result));
  363. }
  364. }
  365. public static function ssoTokenEncode($str,$key='lvzhesso',$expire=0){
  366. $ids=encryption($str);
  367. return authcode($ids,"ENCODE",$key,$expire);
  368. }
  369. public static function ssoTokenDecode($str,$key='lvzhesso')
  370. {
  371. $ids=authcode($str,"DECODE",$key);
  372. try{
  373. return decrypt($ids);
  374. }catch(\Exception $e){
  375. return '';
  376. }
  377. }
  378. /*
  379. 获取url中的主机名
  380. $url -string
  381. return string
  382. */
  383. public static function getHost($url)
  384. {
  385. if(!preg_match('/http[s]:\/\/[\w.]+[\w\/]*[\w.]*\??[\w=&\+\%]*/is',$url)){
  386. return '';
  387. }
  388. $search = '~^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?~i';
  389. $url = trim($url);
  390. preg_match_all($search, $url ,$rr);
  391. return $rr[4][0];
  392. }
  393. /*
  394. 替换特殊字符
  395. $url -string
  396. return string
  397. */
  398. public static function strFilter($str,$is_file=false){
  399. $str = str_replace('`', '', $str);
  400. $str = str_replace('·', '', $str);
  401. $str = str_replace('~', '', $str);
  402. $str = str_replace('!', '', $str);
  403. $str = str_replace('!', '', $str);
  404. $str = str_replace('@', '', $str);
  405. $str = str_replace('#', '', $str);
  406. $str = str_replace('$', '', $str);
  407. $str = str_replace('¥', '', $str);
  408. $str = str_replace('%', '', $str);
  409. $str = str_replace('……', '', $str);
  410. $str = str_replace('&', '', $str);
  411. $str = str_replace('*', '', $str);
  412. $str = str_replace('(', '', $str);
  413. $str = str_replace(')', '', $str);
  414. $str = str_replace('(', '', $str);
  415. $str = str_replace(')', '', $str);
  416. $str = str_replace('-', '', $str);
  417. $str = str_replace('_', '', $str);
  418. $str = str_replace('——', '', $str);
  419. $str = str_replace('+', '', $str);
  420. $str = str_replace('=', '', $str);
  421. $str = str_replace('|', '', $str);
  422. $str = str_replace('\\', '', $str);
  423. $str = str_replace('[', '', $str);
  424. $str = str_replace(']', '', $str);
  425. $str = str_replace('【', '', $str);
  426. $str = str_replace('】', '', $str);
  427. $str = str_replace('{', '', $str);
  428. $str = str_replace('}', '', $str);
  429. $str = str_replace(';', '', $str);
  430. $str = str_replace(';', '', $str);
  431. $str = str_replace(':', '', $str);
  432. $str = str_replace(':', '', $str);
  433. $str = str_replace('\'', '', $str);
  434. $str = str_replace('"', '', $str);
  435. $str = str_replace('“', '', $str);
  436. $str = str_replace('”', '', $str);
  437. $str = str_replace(',', '', $str);
  438. $str = str_replace(',', '', $str);
  439. $str = str_replace('<', '', $str);
  440. $str = str_replace('>', '', $str);
  441. $str = str_replace('《', '', $str);
  442. $str = str_replace('》', '', $str);
  443. $str = str_replace('。', '', $str);
  444. $str = str_replace('/', '', $str);
  445. $str = str_replace('、', '', $str);
  446. $str = str_replace('?', '', $str);
  447. $str = str_replace('?', '', $str);
  448. if(!$is_file){
  449. $str = str_replace('.', '', $str);
  450. }
  451. return trim($str);
  452. }
  453. /**
  454. * 隐藏公司名或人名的中间部分
  455. * @param string $str 需要处理的字符串
  456. * @return string 处理后的字符串
  457. */
  458. public static function maskString($str,$i=3) {
  459. // 获取字符串长度
  460. $len = self::get_string_length($str);
  461. // 如果数组长度小于等于2,则只将第二个字符替换为*
  462. if ($len <= 1) {
  463. return '******';
  464. }elseif ($len == 2) {
  465. return self::msubstr($str,0,1).'*';
  466. } else {
  467. return self::msubstr($str,0,$i).'******'.self::msubstr($str,-$i,$i);
  468. }
  469. }
  470. /**
  471. * 获取人名的最后一个字或者两个字
  472. * @param string $str 需要处理的字符串
  473. * @return string 处理后的字符串
  474. */
  475. public static function getLastName($str,$i=1) {
  476. // 获取字符串长度
  477. $len = self::get_string_length($str);
  478. // 如果数组长度小于等于2,则只将第二个字符替换为*
  479. if ($len < 2) {
  480. return self::msubstr($str,0,1);
  481. }else{
  482. return self::msubstr($str,-$i,$i);
  483. }
  484. }
  485. public static function get_string_length($str) {
  486. // 将字符串转换为 UTF-8 编码
  487. $str = mb_convert_encoding($str, 'UTF-8', mb_detect_encoding($str));
  488. // 返回字符串的字符数
  489. return mb_strlen($str);
  490. }
  491. // 提取身份证中的年龄和性别
  492. public static function getIdforAG($str){
  493. if(!$str){
  494. return false;
  495. }
  496. // 先验证是否为身份证
  497. if(!preg_match('/(^\d{15}$)|(^\d{17}([0-9]|X)$)/',$str)){
  498. return false;
  499. }
  500. $length=strlen($str);
  501. if($length==15){
  502. $sexnum = substr($str,14,1);
  503. $age = date('Y') - '19'.substr($str,6,2);
  504. }else{
  505. $sexnum = substr($str,16,1);
  506. $age = date('Y') - substr($str,6,4);
  507. }
  508. return [
  509. 'gender'=>$sexnum%2==0 ? 0 : 1,
  510. 'age'=>$age
  511. ];
  512. }
  513. /**
  514. * Universally Unique Identifier v4
  515. *
  516. * @param int $b
  517. * @return UUID, if $b returns binary(16)
  518. */
  519. public static function getUuid($b = null)
  520. {
  521. if (function_exists('uuid_create')) {
  522. $uuid = uuid_create();
  523. } else {
  524. $uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff));
  525. }
  526. return $b ? pack('H*', str_replace('-', '', $uuid)) : $uuid;
  527. }
  528. }