524 lines
15 KiB
PHP
524 lines
15 KiB
PHP
<?php
|
|
/**
|
|
* I know no such things as genius,it is nothing but labor and diligence.
|
|
*
|
|
* @copyright (c) 2015~2019 BD All rights reserved.
|
|
* @license http://www.apache.org/licenses/LICENSE-2.0
|
|
* @author BD<657306123@qq.com>
|
|
*/
|
|
|
|
namespace xin\helper;
|
|
|
|
/**
|
|
* 字符串工具类
|
|
*
|
|
* @package xin\helper
|
|
*/
|
|
final class Str{
|
|
|
|
/**
|
|
* 驼峰转下划线缓存
|
|
*
|
|
* @var array
|
|
*/
|
|
protected static $snakeCache = [];
|
|
|
|
/**
|
|
* 下划线转驼峰(首字母小写) 缓存
|
|
*
|
|
* @var array
|
|
*/
|
|
protected static $camelCache = [];
|
|
|
|
/**
|
|
* 下划线转驼峰(首字母大写)
|
|
*
|
|
* @var array
|
|
*/
|
|
protected static $studlyCache = [];
|
|
|
|
/**
|
|
* 检查字符串中是否包含某些字符串
|
|
*
|
|
* @param string $haystack
|
|
* @param string|array $needles
|
|
* @return bool
|
|
*/
|
|
public static function contains($haystack, $needles){
|
|
foreach((array)$needles as $needle){
|
|
if($needle != '' && mb_strpos($haystack, $needle) !== false){
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* 检查字符串是否以某些字符串结尾
|
|
*
|
|
* @param string $haystack
|
|
* @param string|array $needles
|
|
* @return bool
|
|
*/
|
|
public static function endsWith($haystack, $needles){
|
|
foreach((array)$needles as $needle){
|
|
if((string)$needle === static::subString($haystack, -mb_strlen($needle))){
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* 字符串截取,支持中文和其他编码
|
|
*
|
|
* @param string $value 验证的值
|
|
* @param int $start 开始位置
|
|
* @param int $length 截取长度
|
|
* @param string $charset 字符编码
|
|
* @return string
|
|
*/
|
|
public static function subString($value, $start = 0, $length = null, $charset = null){
|
|
if(function_exists("mb_substr"))
|
|
$slice = mb_substr($value, $start, $length, $charset);
|
|
elseif(function_exists('iconv_substr')){
|
|
$length = is_null($length) ? $length = 'iconv_strlen($str, $charset)' : $length;
|
|
$charset = is_null($charset) ? $charset = 'ini_get("iconv.internal_encoding")' : $charset;
|
|
$slice = iconv_substr($value, $start, $length, $charset);
|
|
if(false === $slice){
|
|
$slice = '';
|
|
}
|
|
}else{
|
|
$re ['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
|
|
$re ['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
|
|
$re ['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
|
|
$re ['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
|
|
preg_match_all($re [$charset], $value, $match);
|
|
$slice = join("", array_slice($match [0], $start, $length));
|
|
}
|
|
return $slice;
|
|
}
|
|
|
|
/**
|
|
* 检查字符串是否以某些字符串开头
|
|
*
|
|
* @param string $haystack
|
|
* @param string|array $needles
|
|
* @return bool
|
|
*/
|
|
public static function startsWith($haystack, $needles){
|
|
foreach((array)$needles as $needle){
|
|
if($needle != '' && mb_strpos($haystack, $needle) === 0){
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* 字符串转小写
|
|
*
|
|
* @param string $value
|
|
* @return string
|
|
*/
|
|
public static function lower($value){
|
|
return mb_strtolower($value, 'UTF-8');
|
|
}
|
|
|
|
/**
|
|
* 字符串转大写
|
|
*
|
|
* @param string $value
|
|
* @return string
|
|
*/
|
|
public static function upper($value){
|
|
return mb_strtoupper($value, 'UTF-8');
|
|
}
|
|
|
|
/**
|
|
* 获取字符串的长度
|
|
*
|
|
* @param string $value
|
|
* @return int
|
|
*/
|
|
public static function length($value){
|
|
return mb_strlen($value);
|
|
}
|
|
|
|
/**
|
|
* 驼峰转下划线
|
|
*
|
|
* @param string $value
|
|
* @param string $delimiter
|
|
* @param bool $isCache
|
|
* @return string
|
|
*/
|
|
public static function snake($value, $delimiter = '_', $isCache = true){
|
|
$key = $value;
|
|
|
|
if(isset(static::$snakeCache[$key][$delimiter])){
|
|
return static::$snakeCache[$key][$delimiter];
|
|
}
|
|
|
|
if(!ctype_lower($value)){
|
|
$value = preg_replace('/\s+/u', '', $value);
|
|
|
|
$value = static::lower(preg_replace('/(.)(?=[A-Z])/u', '$1'.$delimiter, $value));
|
|
}
|
|
|
|
return $isCache ? static::$snakeCache[$key][$delimiter] = $value : $value;
|
|
}
|
|
|
|
/**
|
|
* 清除驼峰转下划线缓存
|
|
*/
|
|
public static function clearSnakeCache(){
|
|
self::$snakeCache = [];
|
|
}
|
|
|
|
/**
|
|
* 下划线转驼峰(首字母小写)
|
|
*
|
|
* @param string $value
|
|
* @param bool $isCache
|
|
* @return string
|
|
*/
|
|
public static function camel($value, $isCache = true){
|
|
if(isset(static::$camelCache[$value])){
|
|
return static::$camelCache[$value];
|
|
}
|
|
|
|
$value = lcfirst(static::studly($value));
|
|
return $isCache ? static::$camelCache[$value] = $value : $value;
|
|
}
|
|
|
|
/**
|
|
* 清除下划线转驼峰(首字母小写)缓存
|
|
*/
|
|
public static function clearCamelCache(){
|
|
self::$snakeCache = [];
|
|
}
|
|
|
|
/**
|
|
* 下划线转驼峰(首字母大写)
|
|
*
|
|
* @param string $value
|
|
* @param bool $isCache
|
|
* @return string
|
|
*/
|
|
public static function studly($value, $isCache = true){
|
|
$key = $value;
|
|
|
|
if(isset(static::$studlyCache[$key])){
|
|
return static::$studlyCache[$key];
|
|
}
|
|
|
|
$value = ucwords(str_replace(['-', '_'], ' ', $value));
|
|
$value = str_replace(' ', '', $value);
|
|
|
|
return $isCache ? static::$studlyCache[$key] = $value : $value;
|
|
}
|
|
|
|
/**
|
|
* 清除下划线转驼峰(首字母大写)缓存
|
|
*/
|
|
public static function clearStudlyCache(){
|
|
self::$snakeCache = [];
|
|
}
|
|
|
|
/**
|
|
* 转为首字母大写的标题格式
|
|
*
|
|
* @param string $value
|
|
* @return string
|
|
*/
|
|
public static function title($value){
|
|
return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');
|
|
}
|
|
|
|
/**
|
|
* 实现多种字符编码方式
|
|
*
|
|
* @param string $input 数据源
|
|
* @param string $_output_charset 输出的字符编码
|
|
* @param string $_input_charset 输入的字符编码
|
|
* @return string
|
|
*/
|
|
public static function charsetEncode($input, $_output_charset, $_input_charset){
|
|
if(!isset ($_output_charset))
|
|
$_output_charset = $_input_charset;
|
|
if($_input_charset == $_output_charset || $input == null){
|
|
$output = $input;
|
|
}elseif(function_exists("mb_convert_encoding")){
|
|
$output = mb_convert_encoding($input, $_output_charset, $_input_charset);
|
|
}elseif(function_exists("iconv")){
|
|
$output = iconv($_input_charset, $_output_charset, $input);
|
|
}else{
|
|
throw new \RuntimeException("不支持 $_input_charset 到 $_output_charset 编码!");
|
|
}
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* 实现多种字符解码方式
|
|
*
|
|
* @param string $input 数据源
|
|
* @param string $_input_charset 输入的字符编码
|
|
* @param string $_output_charset 输出的字符编码
|
|
* @return string
|
|
*/
|
|
public static function charsetDecode($input, $_input_charset, $_output_charset){
|
|
if($_input_charset == $_output_charset || $input == null){
|
|
$output = $input;
|
|
}elseif(function_exists("mb_convert_encoding")){
|
|
$output = mb_convert_encoding($input, $_output_charset, $_input_charset);
|
|
}elseif(function_exists("iconv")){
|
|
$output = iconv($_input_charset, $_output_charset, $input);
|
|
}else{
|
|
throw new \RuntimeException("不支持 $_input_charset 到 $_output_charset 解码!");
|
|
}
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* 获取随机字符串
|
|
*
|
|
* @param int $length
|
|
* @param int $type
|
|
* @return string
|
|
*/
|
|
public static function random($length = 16, $type = 5){
|
|
$pool = [
|
|
0 => '0123456789',
|
|
1 => 'abcdefghijklmnopqrstuvwxyz',
|
|
2 => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
|
];
|
|
|
|
$poolStr = '';
|
|
if(0 == $type) $poolStr = $pool[0];
|
|
if(1 == $type) $poolStr = $pool[1];
|
|
if(2 == $type) $poolStr = $pool[2];
|
|
if(3 == $type) $poolStr = $pool[0].$pool[1];
|
|
if(4 == $type) $poolStr = $pool[1].$pool[2];
|
|
if(5 == $type) $poolStr = $pool[0].$pool[1].$pool[2];
|
|
|
|
return self::substr(str_shuffle(str_repeat($poolStr, $length)), 0, $length);
|
|
}
|
|
|
|
/**
|
|
* 截取字符串
|
|
*
|
|
* @param string $string
|
|
* @param int $start
|
|
* @param int|null $length
|
|
* @return string
|
|
*/
|
|
public static function substr($string, $start, $length = null){
|
|
return mb_substr($string, $start, $length, 'UTF-8');
|
|
}
|
|
|
|
/**
|
|
* 生成随机字符串
|
|
*
|
|
* @param string $factor
|
|
* @return string
|
|
*/
|
|
public static function nonceHash32($factor = ''){
|
|
return md5(uniqid(md5(microtime(true).$factor), true));
|
|
}
|
|
|
|
/**
|
|
* 创建订单编号
|
|
*
|
|
* @param string $prefix
|
|
* @return string
|
|
*/
|
|
public static function makeOrderSn($prefix = ''){ // 取出订单编号
|
|
$datetime = date('YmdHis');
|
|
$microtime = explode(' ', microtime());
|
|
$microtime = intval($microtime[0] ? $microtime[0] * 100000 : 100000);
|
|
$nonceStr = substr(implode(null, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
|
|
return $prefix.$datetime.$microtime.$nonceStr;
|
|
}
|
|
|
|
/**
|
|
* 创建一个随机名字
|
|
*
|
|
* @param string $firstName
|
|
* @param int $lastNameLength 名字字数
|
|
* @param string $delimiter
|
|
* @return string
|
|
*/
|
|
public static function createName($firstName = null, $lastNameLength = 2, $delimiter = ''){
|
|
static $data = null;
|
|
if(is_null($data)){
|
|
$data = require_once './name_config.php';
|
|
}
|
|
|
|
//姓氏
|
|
if(empty($firstName)){
|
|
$len = count($data['first_name_list']);
|
|
$firstName = $data['first_name_list'][rand(0, $len - 1)];
|
|
}
|
|
|
|
//名字
|
|
$len = count($data['chars']);
|
|
$lastName = '';
|
|
for($i = 0; $i < $lastNameLength; $i++){
|
|
$lastName .= $data [rand(0, $len - 1)];
|
|
}
|
|
return $firstName.$delimiter.$lastName;
|
|
}
|
|
|
|
/**
|
|
* 解析Url Query
|
|
*
|
|
* @param string $url url地址或URL query参数
|
|
* @return array
|
|
*/
|
|
public static function parseUrlQuery($url){
|
|
$index = strpos($url, "?");
|
|
$url = $index === false ? $url : substr($url, $index);
|
|
parse_str($url, $result);
|
|
return $result;
|
|
//
|
|
// //分隔数据
|
|
// $querys = explode("&", $url);
|
|
// unset($url);
|
|
// $regx = "/\\[(.*?)\\]/";
|
|
// //返回的结果
|
|
// $result = [];
|
|
// foreach($querys as $key => $val){
|
|
// list($name, $value) = explode('=', $val, 2);
|
|
// unset($querys[$key]);
|
|
//
|
|
// $name = trim($name);
|
|
// //是否为数组
|
|
// if(preg_match($regx, $name, $matches)){
|
|
// $matches = $matches[1];
|
|
// $name = substr($name, 0, strpos($name, "[") - 1);
|
|
// if(empty($matches))
|
|
// $result[$name][] = $value;
|
|
// else
|
|
// $result[$name][$matches] = $value;
|
|
// }else{
|
|
// $result[$name] = $value;
|
|
// }
|
|
// }
|
|
// return $result;
|
|
}
|
|
|
|
/**
|
|
* 把数组所有元素按照“参数=参数值”的模式用“&”字符拼接成字符串
|
|
*
|
|
* @param array $params 关联数组
|
|
* @param string $handleFunc 值处理函数
|
|
* @return string
|
|
*/
|
|
public static function buildUrlQuery($params, $handleFunc = null){
|
|
if(!is_callable($handleFunc)) $handleFunc = function($key, $val){
|
|
$type = gettype($val);
|
|
if($type == 'object' || $type == 'array') return '';
|
|
|
|
$val = urlencode($val);
|
|
return $key.'='.$val;
|
|
};
|
|
|
|
$result = '';
|
|
$i = 0;
|
|
foreach($params as $key => $val){
|
|
$str = $handleFunc($key, $val);
|
|
if($str === '') continue;
|
|
$result .= ($i === 0 ? '' : '&').$str;
|
|
$i++;
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* 将XML转换成数组
|
|
*
|
|
* @param string $xml
|
|
* @return mixed
|
|
*/
|
|
public static function parseXml($xml){
|
|
//将XML转为array,禁止引用外部xml实体
|
|
libxml_disable_entity_loader(true);
|
|
$info = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
|
|
return $info;
|
|
}
|
|
|
|
/**
|
|
* 数组转XML(微信)
|
|
*
|
|
* @param array $param 要转换的数组
|
|
* @param string $root 根元素
|
|
* @param string $tag 指定元素标签名称,主要用于索引数组
|
|
* @return string
|
|
*/
|
|
public static function encodeXml($param, $root = 'xml', $tag = ''){
|
|
if(!is_array($param) || count($param) <= 0) return '';
|
|
|
|
$xml = '';
|
|
foreach($param as $key => $val){
|
|
$key = empty($tag) ? $key : $tag;
|
|
if(is_int($val)){
|
|
$xml .= "<".$key.">".$val."</".$key.">";
|
|
$root = !empty($tag) ? '' : $root;
|
|
}elseif(is_array($val)){
|
|
$tempRoot = Arr::isAssoc($param) ? $key : '';
|
|
$tempTag = (Arr::isAssoc($param) && !Arr::isAssoc($val)) ? $key : '';
|
|
$xml .= self::encodeXml($val, $tempRoot, $tempTag);
|
|
}else{
|
|
$xml .= "<".$key."><![CDATA[".$val."]]></".$key.">";
|
|
$root = !empty($tag) ? '' : $root;
|
|
}
|
|
}
|
|
$xml = (empty($root) ? "" : "<$root>").$xml.(empty($root) ? "" : "</$root>");
|
|
return $xml;
|
|
}
|
|
|
|
/**
|
|
* 解析UBB语法
|
|
*
|
|
* @param string $Text 要解析的文本
|
|
* @return mixed|string
|
|
*/
|
|
public static function parseUBB($Text){
|
|
$Text = trim($Text);
|
|
$Text = htmlspecialchars($Text);
|
|
$Text = preg_replace("/\\t/is", " ", $Text);
|
|
$Text = preg_replace("/\\[h1\\](.+?)\\[\\/h1\\]/is", "<h1>\\1</h1>", $Text);
|
|
$Text = preg_replace("/\\[h2\\](.+?)\\[\\/h2\\]/is", "<h2>\\1</h2>", $Text);
|
|
$Text = preg_replace("/\\[h3\\](.+?)\\[\\/h3\\]/is", "<h3>\\1</h3>", $Text);
|
|
$Text = preg_replace("/\\[h4\\](.+?)\\[\\/h4\\]/is", "<h4>\\1</h4>", $Text);
|
|
$Text = preg_replace("/\\[h5\\](.+?)\\[\\/h5\\]/is", "<h5>\\1</h5>", $Text);
|
|
$Text = preg_replace("/\\[h6\\](.+?)\\[\\/h6\\]/is", "<h6>\\1</h6>", $Text);
|
|
$Text = preg_replace("/\\[separator\\]/is", "", $Text);
|
|
$Text = preg_replace("/\\[center\\](.+?)\\[\\/center\\]/is", "<span style=\"text-align: center\">\\1</span>",
|
|
$Text);
|
|
$Text = preg_replace("/\\[url=http:\\/\\/([^\\[]*)\\](.+?)\\[\\/url\\]/is", "<a href=\"http://\\1\" target=\"_blank\">\\2</a>", $Text);
|
|
$Text = preg_replace("/\\[url=([^\\[]*)\\](.+?)\\[\\/url\\]/is", "<a href=\"http://\\1\" target=\"_blank\">\\2</a>", $Text);
|
|
$Text = preg_replace("/\\[url\\]http:\\/\\/([^\\[]*)\\[\\/url\\]/is", "<a href=\"http://\\1\" target=\"_blank\">\\1</a>", $Text);
|
|
$Text = preg_replace("/\\[url\\]([^\\[]*)\\[\\/url\\]/is", "<a href=\"\\1\" target=\"_blank\">\\1</a>", $Text);
|
|
$Text = preg_replace("/\\[img\\](.+?)\\[\\/img\\]/is", "<img src=\"\\1\">", $Text);
|
|
$Text = preg_replace("/\\[color=(.+?)\\](.+?)\\[\\/color\\]/is", "<span style=\"color: \\1\">\\2</span>", $Text);
|
|
$Text = preg_replace("/\\[size=(.+?)\\](.+?)\\[\\/size\\]/is", "<span style=\"font-size: \\1\">\\2</span>", $Text);
|
|
$Text = preg_replace("/\\[sup\\](.+?)\\[\\/sup\\]/is", "<sup>\\1</sup>", $Text);
|
|
$Text = preg_replace("/\\[sub\\](.+?)\\[\\/sub\\]/is", "<sub>\\1</sub>", $Text);
|
|
$Text = preg_replace("/\\[pre\\](.+?)\\[\\/pre\\]/is", "<pre>\\1</pre>", $Text);
|
|
$Text = preg_replace("/\\[email\\](.+?)\\[\\/email\\]/is", "<a href=\"mailto:\\1\">\\1</a>", $Text);
|
|
$Text = preg_replace("/\\[colorTxt\\](.+?)\\[\\/colorTxt\\]/eis", "color_txt('\\1')", $Text);
|
|
$Text = preg_replace("/\\[emot\\](.+?)\\[\\/emot\\]/eis", "emot('\\1')", $Text);
|
|
$Text = preg_replace("/\\[i\\](.+?)\\[\\/i\\]/is", "<i>\\1</i>", $Text);
|
|
$Text = preg_replace("/\\[u\\](.+?)\\[\\/u\\]/is", "<u>\\1</u>", $Text);
|
|
$Text = preg_replace("/\\[b\\](.+?)\\[\\/b\\]/is", "<b>\\1</b>", $Text);
|
|
$Text = preg_replace("/\\[quote\\](.+?)\\[\\/quote\\]/is", " <div class=\"quote\"><h5>引用:</h5><blockquote>\\1</blockquote></div>", $Text);
|
|
$Text = preg_replace("/\\[code\\](.+?)\\[\\/code\\]/eis", "highlight_code('\\1')", $Text);
|
|
$Text = preg_replace("/\\[php\\](.+?)\\[\\/php\\]/eis", "highlight_code('\\1')", $Text);
|
|
$Text = preg_replace("/\\[sig\\](.+?)\\[\\/sig\\]/is", "<div class=\"sign\">\\1</div>", $Text);
|
|
$Text = preg_replace("/\\n/is", "<br/>", $Text);
|
|
return $Text;
|
|
}
|
|
}
|