diff --git a/libs/str-utils/README.md b/libs/str-utils/README.md index 9a99421..0850e0c 100644 --- a/libs/str-utils/README.md +++ b/libs/str-utils/README.md @@ -1,4 +1,13 @@ -# string utils for php +# str utils + +string utils for php + +contains: + +- html string helper +- json string helper +- url string helper +- common string helper ## install diff --git a/libs/str-utils/composer.json b/libs/str-utils/composer.json index c87ac2e..34a50ec 100644 --- a/libs/str-utils/composer.json +++ b/libs/str-utils/composer.json @@ -27,8 +27,6 @@ } }, "suggest": { - "inhere/simple-print-tool": "Very lightweight data printing tools", "inhere/php-validate": "Very lightweight data validate tool", - "inhere/console": "a lightweight php console application library." } } diff --git a/libs/str-utils/phpunit.xml.dist b/libs/str-utils/phpunit.xml.dist index 6052813..26bd767 100644 --- a/libs/str-utils/phpunit.xml.dist +++ b/libs/str-utils/phpunit.xml.dist @@ -8,7 +8,6 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" stopOnFailure="false" - > diff --git a/libs/str-utils/src/HtmlHelper.php b/libs/str-utils/src/HtmlHelper.php index 057792f..c9be2f5 100644 --- a/libs/str-utils/src/HtmlHelper.php +++ b/libs/str-utils/src/HtmlHelper.php @@ -23,7 +23,7 @@ class HtmlHelper */ public static function encode($text, $charset = 'utf-8'): string { - return htmlspecialchars($text, ENT_QUOTES, $charset); + return \htmlspecialchars($text, ENT_QUOTES, $charset); } /** @@ -34,7 +34,7 @@ public static function encode($text, $charset = 'utf-8'): string */ public static function decode($text): string { - return htmlspecialchars_decode($text, ENT_QUOTES); + return \htmlspecialchars_decode($text, ENT_QUOTES); } /** @@ -50,11 +50,11 @@ public static function encodeArray($data, $charset = 'utf-8'): array foreach ($data as $key => $value) { if (\is_string($key)) { - $key = htmlspecialchars($key, ENT_QUOTES, $charset); + $key = \htmlspecialchars($key, ENT_QUOTES, $charset); } if (\is_string($value)) { - $value = htmlspecialchars($value, ENT_QUOTES, $charset); + $value = \htmlspecialchars($value, ENT_QUOTES, $charset); } elseif (\is_array($value)) { $value = static::encodeArray($value); } @@ -86,19 +86,19 @@ public static function escape($data, int $type = 0, $encoding = 'UTF-8') $data[$k] = self::escape($data, $type, $encoding); } + return $data; + } + + // 默认使用 htmlspecialchars() + if (!$type) { + $data = \htmlspecialchars($data, \ENT_QUOTES, $encoding); } else { - // 默认使用 htmlspecialchars() - if (!$type) { - $data = htmlspecialchars($data, ENT_QUOTES, $encoding); - } else { - $data = htmlentities($data, ENT_QUOTES, $encoding); - } + $data = \htmlentities($data, \ENT_QUOTES, $encoding); + } - //如‘志’这样的16进制的html字符,为了防止这样的字符被错误转译,使用正则进行匹配,把这样的字符又转换回来。 - if (strpos($data, '&#')) { - $data = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', - '&\\1', $data); - } + //如‘志’这样的16进制的html字符,为了防止这样的字符被错误转译,使用正则进行匹配,把这样的字符又转换回来。 + if (\strpos($data, '&#')) { + $data = \preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $data); } return $data; @@ -119,9 +119,9 @@ public static function unescap($data, $type = 0, $encoding = 'UTF-8') } } elseif (!$type) {//默认使用 htmlspecialchars_decode() - $data = htmlspecialchars_decode($data, ENT_QUOTES); + $data = \htmlspecialchars_decode($data, \ENT_QUOTES); } else { - $data = html_entity_decode($data, ENT_QUOTES, $encoding); + $data = \html_entity_decode($data, \ENT_QUOTES, $encoding); } return $data; @@ -144,7 +144,7 @@ public static function stripImages(string $string): string */ public static function stripIframes(string $string): string { - return preg_replace('#(<[/]?iframe.*>)#U', '', $string); + return \preg_replace('#(<[/]?iframe.*>)#U', '', $string); } /** @@ -154,7 +154,7 @@ public static function stripIframes(string $string): string */ public static function stripScript(string $string): string { - return preg_replace('/]*>.*?/si', '', $string); + return \preg_replace('/]*>.*?/si', '', $string); } /** @@ -164,7 +164,7 @@ public static function stripScript(string $string): string */ public static function stripStyle(string $string): string { - return preg_replace('/]*>.*?/si', '', $string); + return \preg_replace('/]*>.*?/si', '', $string); } /** @@ -172,17 +172,17 @@ public static function stripStyle(string $string): string * @param bool|true $onlySrc * @return array */ - public static function findImages(string $html, bool $onlySrc = true): array + public static function matchImages(string $html, bool $onlySrc = true): array { // $preg = '//i'; $preg = '//i'; - if (!preg_match_all($preg, trim($html), $images)) { + if (!\preg_match_all($preg, trim($html), $images)) { return []; } if ($onlySrc) { - return array_key_exists(1, $images) ? $images[1] : []; + return \array_key_exists(1, $images) ? $images[1] : []; } return $images; @@ -194,7 +194,7 @@ public static function findImages(string $html, bool $onlySrc = true): array */ public static function minify(string $html): string { - $search = [ + $search = [ '/(?:(?:\/\*(?:[^*]|(?:\*+[^*\/]))*\*+\/)|(?:(?[^\S ]+/s', @@ -203,6 +203,6 @@ public static function minify(string $html): string ]; $replace = [' ', ' ', '>', '<', '\\1']; - return preg_replace($search, $replace, $html); + return \preg_replace($search, $replace, $html); } } diff --git a/libs/str-utils/src/JsonHelper.php b/libs/str-utils/src/JsonHelper.php index 6a15336..9102e52 100644 --- a/libs/str-utils/src/JsonHelper.php +++ b/libs/str-utils/src/JsonHelper.php @@ -135,9 +135,10 @@ public static function format($input, $output = false, array $options = []) $options = \array_merge($default, $options); if (\file_exists($input) && (empty($options['file']) || !\is_file($options['file']))) { - $dir = \dirname($input); + $dir = \dirname($input); $name = \basename($input, '.json'); $file = $dir . '/' . $name . '.' . $options['type'] . '.json'; + // save to options $options['file'] = $file; } @@ -155,18 +156,18 @@ public static function saveAs(string $data, string $output, array $options = []) { $default = ['type' => 'min', 'file' => '']; $options = array_merge($default, $options); - $dir = \dirname($output); + $saveDir = \dirname($output); - if (!\file_exists($dir)) { - throw new \RuntimeException('设置的json文件输出' . $dir . '目录不存在!'); + if (!\file_exists($saveDir)) { + throw new \RuntimeException('设置的json文件输出' . $saveDir . '目录不存在!'); } $name = \basename($output, '.json'); - $file = $dir . '/' . $name . '.' . $options['type'] . '.json'; + $file = $saveDir . '/' . $name . '.' . $options['type'] . '.json'; + // 去掉空白 if ($options['type '] === 'min') { - // 去掉空白 - $data = (string)\preg_replace('/(?!\w)\s*?(?!\w)/i', '', $data); + $data = \preg_replace('/(?!\w)\s*?(?!\w)/i', '', $data); } return \file_put_contents($file, $data); diff --git a/libs/str-utils/src/StringHelper.php b/libs/str-utils/src/StringHelper.php index 9fe8e29..365a3d1 100644 --- a/libs/str-utils/src/StringHelper.php +++ b/libs/str-utils/src/StringHelper.php @@ -111,7 +111,7 @@ public static function regexMatch(string $value, string $rule): bool ]; $value = \trim($value); - $name = \strtolower($rule); + $name = \strtolower($rule); // 检查是否有内置的正则表达式 if (isset($validate[$name])) { @@ -192,14 +192,14 @@ public static function absLen(string $str): int } if (\function_exists('mb_strwidth')) { - return mb_strwidth($str, 'utf-8'); + return \mb_strwidth($str, 'utf-8'); } if (\function_exists('mb_strlen')) { - return mb_strlen($str, 'utf-8'); + return \mb_strlen($str, 'utf-8'); } - preg_match_all('/./u', $str, $ar); + \preg_match_all('/./u', $str, $ar); return \count($ar[0]); } @@ -210,13 +210,13 @@ public static function absLen(string $str): int /** * ********************** 生成一定长度的随机字符串函数 ********************** - * @param $length - 随机字符串长度 + * @param int $length - 随机字符串长度 * @param array|string $param - * @internal param string $chars * @return string * @throws \Exception */ - public static function random($length, array $param = []): string + public static function random(int $length, array $param = []): string { $param = \array_merge([ 'prefix' => '', @@ -225,8 +225,8 @@ public static function random($length, array $param = []): string ], $param); $chars = $param['chars']; - $max = \strlen($chars) - 1; //strlen($chars) 计算字符串的长度 - $str = ''; + $max = \strlen($chars) - 1; //strlen($chars) 计算字符串的长度 + $str = ''; for ($i = 0; $i < $length; $i++) { $str .= $chars[random_int(0, $max)]; @@ -299,7 +299,7 @@ public static function nl2br(string $str): string return \str_replace(["\r\n", "\r", "\n"], '
', $str); } - public function lower(string $str): string + public static function lower(string $str): string { return static::strtolower($str); } @@ -313,7 +313,7 @@ public static function strtolower(string $str): string return \function_exists('mb_strtolower') ? \mb_strtolower($str, 'utf-8') : \strtolower($str); } - public function upper(string $str): string + public static function upper(string $str): string { return static::strtoupper($str); } @@ -351,6 +351,119 @@ public static function ucwords(string $str): string \ucwords(self::strtolower($str)); } + /** + * @param string $str + * @param bool $upperFirstChar + * @return mixed + */ + public static function camel(string $str, bool $upperFirstChar = false): string + { + return self::toCamelCase($str, $upperFirstChar); + } + + /** + * @param string $str + * @param bool $upperFirstChar + * @return mixed + */ + public static function toCamel(string $str, bool $upperFirstChar = false): string + { + return self::toCamelCase($str, $upperFirstChar); + } + + /** + * to camel + * @param string $name + * @param bool $upperFirst + * @return string + */ + public static function camelCase(string $name, bool $upperFirst = false): string + { + $name = \trim($name, '-_'); + + // convert 'first-second' to 'firstSecond' + if (\strpos($name, '-')) { + $name = \ucwords(\str_replace('-', ' ', $name)); + $name = \str_replace(' ', '', \lcfirst($name)); + } + + return $upperFirst ? \ucfirst($name) : $name; + } + + /** + * Translates a string with underscores into camel case (e.g. first_name -> firstName) + * @param string $str + * @param bool $upperFirst + * @return mixed + */ + public static function toCamelCase(string $str, bool $upperFirst = false): string + { + $str = (string)self::strtolower($str); + + if ($upperFirst) { + $str = self::ucfirst($str); + } + + return \preg_replace_callback('/_+([a-z])/', function ($c) { + return \strtoupper($c[1]); + }, $str); + } + + public static function snake(string $str, string $sep = '_'): string + { + return self::toSnakeCase($str, $sep); + } + + public static function toSnake(string $str, string $sep = '_'): string + { + return self::toSnakeCase($str, $sep); + } + + /** + * Transform a CamelCase string to underscore_case string + * @param string $str + * @param string $sep + * @return string + */ + public static function toSnakeCase(string $str, string $sep = '_'): string + { + // 'CMSCategories' => 'cms_categories' + // 'RangePrice' => 'range_price' + return self::lower(\trim(\preg_replace('/([A-Z][a-z])/', $sep . '$1', $str), $sep)); + } + + /** + * 驼峰式 <=> 下划线式 + * @param string $str [description] + * @param bool $toCamelCase + * true : 驼峰式 => 下划线式 + * false : 驼峰式 <= 下划线式 + * @return string + */ + public static function nameChange(string $str, bool $toCamelCase = true): string + { + $str = \trim($str); + + // 默认 :下划线式 =>驼峰式 + if ($toCamelCase) { + if (\strpos($str, '_') === false) { + return $str; + } + + $arr_char = \explode('_', \strtolower($str)); + $newString = \array_shift($arr_char); + + foreach ($arr_char as $val) { + $newString .= \ucfirst($val); + } + + return $newString; + } + + // 驼峰式 => 下划线式 + return \strtolower(\preg_replace('/((?<=[a-z])(?=[A-Z]))/', '_', $str)); + } + //////////////////////////////////////////////////////////////////////// /// Convert to array //////////////////////////////////////////////////////////////////////// @@ -385,23 +498,28 @@ public static function toArray(string $str, string $sep = ','): array */ public static function str2array(string $str, string $sep = ','): array { - $str = trim($str, "$sep "); + $str = \trim($str, "$sep "); if (!$str) { return []; } - return \preg_split("/\s*$sep\s*/", $str, -1, PREG_SPLIT_NO_EMPTY); + return \preg_split("/\s*$sep\s*/", $str, -1, \PREG_SPLIT_NO_EMPTY); + } + + public static function explode(string $str, string $separator = '.'): array + { + return static::split2Array($str, $separator); } /** - * @param string $path + * @param string $str * @param string $separator * @return array */ - public static function split2Array(string $path, string $separator = '.'): array + public static function split2Array(string $str, string $separator = '.'): array { - return \array_values(\array_filter(\explode($separator, $path), '\strlen')); + return \array_values(\array_filter(\explode($separator, $str), '\trim')); } /** @@ -419,8 +537,8 @@ public static function splitByWidth(string $string, int $width): array } $utf8String = \mb_convert_encoding($string, 'utf8', $encoding); - $lines = []; - $line = ''; + $lines = []; + $line = ''; foreach (\preg_split('//u', $utf8String) as $char) { // test if $char could be appended to current line @@ -431,7 +549,7 @@ public static function splitByWidth(string $string, int $width): array // if not, push current line to array and make new line $lines[] = \str_pad($line, $width); - $line = $char; + $line = $char; } if ('' !== $line) { @@ -521,17 +639,17 @@ public static function zhSubStr($str, $start = 0, $length = 0, $charset = 'utf-8 $slice = \mb_substr($str, $start, $length, $charset); } else { - $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/"; + $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])/"; + $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/"; + $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/"; \preg_match_all($re[$charset], $str, $match); if (\count($match[0]) <= $length) { return $str; } - $slice = implode('', \array_slice($match[0], $start, $length)); + $slice = \implode('', \array_slice($match[0], $start, $length)); } return (bool)$suffix ? $slice . '…' : $slice; @@ -568,7 +686,7 @@ public static function truncate2(string $str, int $start, int $length = null): s { if (!$length) { $length = $start; - $start = 0; + $start = 0; } if (\strlen($str) <= $length) { @@ -599,10 +717,10 @@ public static function truncate3(string $text, int $length = 120, array $options 'html' => true ]; - $options = array_merge($default, $options); + $options = array_merge($default, $options); $ellipsis = $options['ellipsis']; - $exact = $options['exact']; - $html = $options['html']; + $exact = $options['exact']; + $html = $options['html']; /** * @var string $ellipsis @@ -610,13 +728,13 @@ public static function truncate3(string $text, int $length = 120, array $options * @var bool $html */ if ($html) { - if (self::strlen(preg_replace('/<.*?>/', '', $text)) <= $length) { + if (self::strlen(\preg_replace('/<.*?>/', '', $text)) <= $length) { return $text; } - $total_length = self::strlen(strip_tags($ellipsis)); - $open_tags = $tags = []; - $truncate = ''; + $total_length = self::strlen(\strip_tags($ellipsis)); + $open_tags = $tags = []; + $truncate = ''; preg_match_all('/(<\/?([\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER); foreach ($tags as $tag) { @@ -630,12 +748,12 @@ public static function truncate3(string $text, int $length = 120, array $options } } } - $truncate .= $tag[1]; + $truncate .= $tag[1]; $content_length = self::strlen(preg_replace('/&[0-9a-z]{2,8};|&#[\d]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3])); if ($content_length + $total_length > $length) { - $left = $length - $total_length; + $left = $length - $total_length; $entities_length = 0; if (preg_match_all('/&[0-9a-z]{2,8};|&#[\d]{1,7};|&#x[0-9a-f]{1,6};/i', $tag[3], $entities, @@ -654,7 +772,7 @@ public static function truncate3(string $text, int $length = 120, array $options break; } - $truncate .= $tag[3]; + $truncate .= $tag[3]; $total_length += $content_length; if ($total_length >= $length) { @@ -675,7 +793,7 @@ public static function truncate3(string $text, int $length = 120, array $options $spacepos = self::strrpos($truncate, ' '); if ($html) { $truncate_check = self::substr($truncate, 0, $spacepos); - $last_open_tag = self::strrpos($truncate_check, '<'); + $last_open_tag = self::strrpos($truncate_check, '<'); $last_close_tag = self::strrpos($truncate_check, '>'); if ($last_open_tag > $last_close_tag) { @@ -717,115 +835,6 @@ public static function truncate3(string $text, int $length = 120, array $options return $truncate; } - /** - * @param string $str - * @param bool $upperFirstChar - * @return mixed - */ - public static function camel(string $str, bool $upperFirstChar = false): string - { - return self::toCamelCase($str, $upperFirstChar); - } - - /** - * @param string $str - * @param bool $upperFirstChar - * @return mixed - */ - public static function toCamel(string $str, bool $upperFirstChar = false): string - { - return self::toCamelCase($str, $upperFirstChar); - } - - /** - * to camel - * @param string $name - * @param bool $upperFirst - * @return string - */ - public static function camelCase(string $name, bool $upperFirst = false): string - { - $name = \trim($name, '-_'); - - // convert 'first-second' to 'firstSecond' - if (\strpos($name, '-')) { - $name = \ucwords(\str_replace('-', ' ', $name)); - $name = \str_replace(' ', '', \lcfirst($name)); - } - - return $upperFirst ? \ucfirst($name) : $name; - } - - /** - * Translates a string with underscores into camel case (e.g. first_name -> firstName) - * @prototype string public static function toCamelCase(string $str[, bool $capitalise_first_char = false]) - * @param $str - * @param bool $upperFirstChar - * @return mixed - */ - public static function toCamelCase(string $str, bool $upperFirstChar = false): string - { - $str = (string)self::strtolower($str); - - if ($upperFirstChar) { - $str = self::ucfirst($str); - } - - return \preg_replace_callback('/_+([a-z])/', function ($c) { - return \strtoupper($c[1]); - }, $str); - } - - public static function toSnake(string $str, string $sep = '_'): string - { - return self::toSnakeCase($str, $sep); - } - - /** - * Transform a CamelCase string to underscore_case string - * @param string $str - * @param string $sep - * @return string - */ - public static function toSnakeCase(string $str, string $sep = '_'): string - { - // 'CMSCategories' => 'cms_categories' - // 'RangePrice' => 'range_price' - return self::strtolower(trim(preg_replace('/([A-Z][a-z])/', $sep . '$1', $str), $sep)); - } - - /** - * 驼峰式 <=> 下划线式 - * @param string $str [description] - * @param bool $toCamelCase - * true : 驼峰式 => 下划线式 - * false : 驼峰式 <= 下划线式 - * @return string - */ - public static function nameChange(string $str, bool $toCamelCase = true): string - { - $str = trim($str); - - // 默认 :下划线式 =>驼峰式 - if ($toCamelCase) { - if (strpos($str, '_') === false) { - return $str; - } - - $arr_char = explode('_', strtolower($str)); - $newString = array_shift($arr_char); - - foreach ($arr_char as $val) { - $newString .= ucfirst($val); - } - - return $newString; - } - - // 驼峰式 => 下划线式 - return \strtolower(preg_replace('/((?<=[a-z])(?=[A-Z]))/', '_', $str)); - } - //////////////////////////////////////////////////////////////////////// /// Format ////////////////////////////////////////////////////////////////////////