PHP字符串的常用函数
参考链接 https://www.php.net/manual/zh/ref.strings.php
PHP常常需要操作字符串,如验证用户表单数据,返回文档需要的字符串格式,今天我们梳理下日常开发中常常用到的字符串操作函数。
因为考虑到编码的不同,建议开启mbstring
扩展后,使用mb_
函数去操作字符串。
1. 统计字符串长度
- mb_strlen — 获取字符串的长度
mb_strlen($str,'utf-8'); //可以指定编码
2. 比较字符串
-
strcmp — 二进制安全字符串比较
-
strcasecmp — 二进制安全比较字符串(不区分大小写)
strcmp(string $string1, string $string2): int
如果
string1
小于string2
返回-1
;如果string1
大于string2
返回1
;如果两者相等,返回0
。 -
strnatcmp — 使用自然排序算法比较字符串
-
strnatcasecmp — 使用“自然顺序”算法比较字符串(不区分大小写)
strnatcmp(string $string1, string $string2): int
$arr1 = $arr2 = array("img12.png", "img10.png", "img2.png", "img1.png"); echo "Standard string comparison\n"; usort($arr1, "strcmp"); print_r($arr1); /* 非自然顺序 Array ( [0] => img1.png [1] => img10.png [2] => img12.png [3] => img2.png ) */ echo "\nNatural order string comparison\n"; usort($arr2, "strnatcmp"); print_r($arr2); /* 自然顺序,更符合直觉 Array ( [0] => img1.png [1] => img2.png [2] => img10.png [3] => img12.png ) */
-
substr_compare — 二进制安全比较字符串(从偏移位置比较指定长度)
substr_compare( string $haystack, string $needle, int $offset, ?int $length = null, bool $case_insensitive = false ): int
haystack
待比较的第一个字符串。
needle
待比较的第二个字符串。
offset
比较开始的位置。如果为负数,则从字符串结尾处开始算起。
length
比较的长度。默认值为
needle
的长度与haystack
的长度减去位置偏移量offset
后二者中的较大者。case_insensitive
如果
case_insensitive
为true
,比较将不区分大小写。echo substr_compare("abcde", "ab", 0, 2); // 0 比较头两个字符 echo substr_compare("abcde", "de", -2, 2); // 0 比较尾两个字符 echo substr_compare("abcde", "bcg", 1, 2); // 0 echo substr_compare("abcde", "BC", 1, 2, true); // 0 不区分大小写 echo substr_compare("abcde", "bc", 1, 3); // 1 'bcd' 大于 'bc' echo substr_compare("abcde", "cd", 1, 2); // -1 'bc' 小于 'cd' echo substr_compare("abcde", "abc", 5, 1); //-1 字符串结尾标志 echo substr_compare("abcde", "abc", 6, 1); //false 超出字符串结尾标志,php7会返回false,php8会报错ValueError
-
strncmp — 二进制安全比较字符串开头的若干个字符
-
strncasecmp — 二进制安全比较字符串开头的若干个字符(不区分大小写)
strncmp(string $string1, string $string2, int $length): int
以指定两个字符串比较时使用的长度
echo strncmp('Hello John', 'Hello Doe', 5); //0 比较前5个字符
3. 切割字符串
-
chunk_split — 将字符串分割成小块
var_dump(chunk_split("abcd",1,'-')); //string(8) "a-b-c-d-"
-
str_split — 将字符串转换为数组
var_dump(str_split("abcd",2)); /* array(2) { [0]=> string(2) "ab" [1]=> string(2) "cd" } */
-
explode() - 使用一个字符串分割另一个字符串
explode(string $separator, string $string, int $limit = PHP_INT_MAX): array
- separator
边界上的分隔字符。
- string
输入的字符串。
- limit
如果设置了
limit
参数并且是正数,则返回的数组包含最多limit
个元素,而最后那个元素将包含string
的剩余部分。如果
limit
参数是负数,则返回除了最后的-limit
个元素外的所有元素。如果
limit
是 0,则会被当做 1。$pizza = "piece1 piece2 piece3 piece4 piece5 piece6"; $pieces = explode(" ", $pizza,3); var_dump($pieces); /* array(3) { [0]=> string(6) "piece1" [1]=> string(6) "piece2" [2]=> string(27) "piece3 piece4 piece5 piece6" } */
4. 剔除字符串
-
trim — 去除字符串首尾处的空白字符(或者其他字符)
-
rtrim — 删除字符串末端的空白字符(或者其他字符)
-
chop — rtrim 的别名
-
ltrim — 删除字符串开头的空白字符(或其他字符)
trim(string $string, string $characters = " \n\r\t\v\x00"): string
var_dump(trim("123,",',')); //string(3) "123"
5. 填充字符串
-
str_pad — 使用另一个字符串填充字符串为指定长度
str_pad( string $string, int $length, string $pad_string = " ", int $pad_type = STR_PAD_RIGHT ): string
- 如果填充字符的长度不能被
pad_string
整除,那么pad_string
可能会被缩短。 - 可选的
pad_type
参数的可能值为STR_PAD_RIGHT
,STR_PAD_LEFT
或STR_PAD_BOTH
。如果没有指定pad_type
,则假定它是STR_PAD_RIGHT
。
echo str_pad('Alien', 10, "-=", STR_PAD_LEFT); //-=-=-Alien 缩短了$pad_string 以保证长度
- 如果填充字符的长度不能被
6. 查找字符串
-
strpos — 查找字符串首次出现的位置
strpos(string $haystack, string $needle, int $offset = 0): int|false
echo strpos('abcdabcd', 'ab'); //0
类似的还有:
-
strrchr — 查找指定字符在字符串中的最后一次出现
-
stripos — 查找字符串首次出现的位置(不区分大小写)
-
strpbrk — 在字符串中查找一组字符的任何一个字符
$text = 'This is a Simple text.'; // 输出 "is is a Simple text.",因为 'i' 先被匹配 echo strpbrk($text, 'mi');
-
strstr — 查找字符串的首次出现
$email = 'name@example.com'; $domain = strstr($email, '@'); echo $domain; // 打印 @example.com $user = strstr($email, '@', true); echo $user; // 打印 name
-
substr_count — 计算字串出现的次数
substr_count( string $haystack, string $needle, int $offset = 0, ?int $length = null ): int
- offset
开始计数的偏移位置。如果是负数,就从字符的末尾开始统计。
- length
指定偏移位置之后的最大搜索长度。如果偏移量加上这个长度的和大于
haystack
的总长度,则打印警告信息。 负数的长度 length 是从haystack
的末尾开始统计的。$text = 'This is a test'; echo strlen($text); // 14 echo substr_count($text, 'is'); // 2 // 字符串被简化为 's is a test',因此输出 1 echo substr_count($text, 'is', 3); // 字符串被简化为 's i',所以输出 0 echo substr_count($text, 'is', 3, 3); // 因为 5+10 > 14,所以生成警告 echo substr_count($text, 'is', 5, 10); // 输出 1,因为该函数不计算重叠字符串 $text2 = 'gcdgcdgcd'; echo substr_count($text2, 'gcdgcd');
6. 替换字符串
-
str_replace — 子字符串替换
str_replace( array|string $search, array|string $replace, string|array $subject, int &$count = null ): string|array
//"<body text='%body%'>" 中将 "%body%" 替换为 "black",将替换次数记录到变量$count中 var_dump(str_replace("%body%", "black", "<body text='%body%'>",$count)); //string(19) "<body text='black'>" var_dump($count); //int(1) //将字符串'Hello World of PHP'中如果匹配了["a", "e", "i", "o", "u", "A", "E", "I", "O", "U"]这些字符,替换为空字符串"" var_dump(str_replace(array("a", "e", "i", "o", "u", "A", "E", "I", "O", "U"), "", "Hello World of PHP")); //string(14) "Hll Wrld f PHP" //查找"fruits", "vegetables", "fiber",一一对应,替换为:"pizza", "beer", "ice cream" $phrase = "You should eat fruits, vegetables, and fiber every day."; $healthy = array("fruits", "vegetables", "fiber"); $yummy = array("pizza", "beer", "ice cream"); $newphrase = str_replace($healthy, $yummy, $phrase); var_dump($newphrase); //string(52) "You should eat pizza, beer, and ice cream every day."
-
strtr — 转换字符或替换字串
- 用法一:
strtr(string $string, array $replace_pairs): string
不能使用php8的命名参数
注意优先替换(没有选择 “h”,因为有更长的匹配项)以及不再搜索已替换的文本。
$trans = array("h" => "-", "hello" => "hi", "hi" => "hello"); echo strtr("hi all, I said hello", $trans); //hello all, I said hi
- 用法二:
strtr(string $string, string $from, string $to): string
使用三个参数,strtr() 将按字节替换;
echo strtr("baab", "ab", "01"); //输出:1001
-
substr_replace — 替换字符串的子串
substr_replace( array|string $string, array|string $replace, array|int $offset, array|int|null $length = null ): string|array
参数:
- length
如果设定了这个参数并且为正数,表示
string
中被替换的子字符串的长度。如果设定为负数,它表示待替换的子字符串结尾处距离string
末端的字符个数。如果没有提供此参数,那么它默认为 strlen(string
)(字符串的长度)。当然,如果length
为 0,那么这个函数的功能为将replace
插入到string
的offset
位置处。$var = 'ABCDEFGH:/MNRPQR/'; /* 替换第一个位置的字符 */ echo substr_replace($var, 'bob', 0,1); //输出:bobBCDEFGH:/MNRPQR/ /* 替换所有的字符串 */ echo substr_replace($var, 'bob', 0, strlen($var)); //输出:bob /* 将 “bob” 插入到 $var 的开头处。*/ echo substr_replace($var, 'bob', 0, 0) . "<br />\n"; //输出:bobABCDEFGH:/MNRPQR/ /* 用作数组 */ $input = array('A: XXX', 'B: XXX', 'C: XXX'); // 简单用例:将每个字符串使用 YYY 替换为 XXX。 echo implode('; ', substr_replace($input, 'YYY', 3, 3))."\n"; //输出;A: YYY; B: YYY; C: YYY
-
preg_replace — 执行一个正则表达式的搜索和替换
preg_replace( string|array $pattern, // 要查找的字符串格式 string|array $replacement, // 目标字符串格式 string|array $subject, // 待处理字符串 int $limit = -1, // 替换次数,-1为全部替换 int &$count = null // 已替换了多少次 ): string|array|null
$string = 'April 15, 2003'; $pattern = '/(\w+) (\d+), (\d+)/i'; $replacement = '${1}1,$3'; echo preg_replace($pattern, $replacement, $string); // 输出:April1,2003
7. 处理html编码
-
htmlspecialchars — 将特殊字符转换为 HTML 实体
htmlspecialchars( string $string, // 待处理字符串 int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, // 设置转义处理细节、无效单元序列、文档类型 ?string $encoding = null, // 编码格式 bool $double_encode = true // 关闭 double_encode 时,PHP 不会转换现有的 HTML 实体, 默认是全部转换。 ): string
参数
-
flags
ENT_COMPAT 会转换双引号,不转换单引号。
ENT_QUOTES 既转换双引号也转换单引号。
ENT_NOQUOTES 单/双引号都不转换
ENT_IGNORE 静默丢弃无效的代码单元序列,而不是返回空字符串。 不建议使用此标记, 因为它» 可能有安全影响。
ENT_SUBSTITUTE 替换无效的代码单元序列为 Unicode 代替符(Replacement Character), U+FFFD (UTF-8) 或者 � (其他),而不是返回空字符串。
ENT_DISALLOWED 为文档的无效代码点替换为 Unicode 代替符(Replacement Character): U+FFFD (UTF-8),或 �(其他),而不是把它们留在原处。 比如以下情况下就很有用:要保证 XML 文档嵌入额外内容时格式合法。
ENT_HTML401 以 HTML 4.01 处理代码。
ENT_XML1 以 XML 1 处理代码。
ENT_XHTML 以 XHTML 处理代码。
ENT_HTML5 以 HTML 5 处理代码。
-
-
htmlspecialchars_decode — 将特殊的 HTML 实体转换回普通字符
htmlspecialchars_decode( string $string, int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ): string
-
htmlentities — 将字符转换为 HTML 转义字符
htmlentities( string $string, int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, ?string $encoding = null, bool $double_encode = true ): string
$str = "A 'quote' is <b>bold</b>"; // 输出: A 'quote' is <b>bold</b> echo htmlentities($str);
-
html_entity_decode — 将HTML 转义字符转换为字符
8. 加密
-
md5 — 计算字符串的 md5 散列值
md5(string $string, bool $binary = false): string
参数:
- binary
如果可选的 binary 被设置为 true,那么 md5 摘要将以 16 字符长度的原始二进制格式返回。
- binary
-
sha1 — 计算字符串的 sha1 散列值
sha1(string $string, bool $binary = false): string
参数:
-
binary
如果可选的
binary
参数被设置为true
, 那么 sha1 摘要将以 20 字符长度的原始二进制格式返回, 否则返回值为 40 字符长度的十六进制数。
-
-
crypt — 单向字符串散列
-
hash_equals — 可防止时序攻击的字符串比较
推荐使用 password_hash()
password_hash() 使用了强散列,产生足够强的盐值,并自动应用合适的轮次。password_hash() 是crypt() 的简单封装,并且与现有的密码散列兼容
$user_input = 'rasmuslerdorf'; $hashed_password = '$6$rounds=1000000$NJy4rIPjpOaU$0ACEYGg/aKCY3v8O8AfyiO7CTfZQ8/W231Qfh2tRLmfdvFD6XfHk12u6hMr9cYIA4hnpjLNSTRtUwYr9km9Ij/'; // 验证现有的 crypt() 哈希值,以便与非 PHP 软件兼容。 if (hash_equals($hashed_password, crypt($user_input, $hashed_password))) { echo "Password verified!"; }
-
password_hash — 创建密码的散列(hash)
password_hash(string $password, string|int|null $algo, array $options = []): string
参数:
- algo 加密算法
PASSWORD_DEFAULT
- 使用 bcrypt 算法 (PHP 5.5.0 默认)。 注意,该常量会随着 PHP 加入更新更高强度的算法而改变。 所以,使用此常量生成结果的长度将在未来有变化。 因此,数据库里储存结果的列可超过60个字符(最好是255个字符)。PASSWORD_BCRYPT
- 使用CRYPT_BLOWFISH
算法创建散列。 这会产生兼容使用 “ 2 y 2y 2y” 的 crypt()。 结果将会是 60 个字符的字符串, 或者在失败时返回false
。PASSWORD_ARGON2I
- 使用 Argon2i 散列算法创建散列。 只有在 PHP 编译时加入 Argon2 支持时才能使用该算法。PASSWORD_ARGON2ID
- 使用 Argon2id 散列算法创建散列。 只有在 PHP 编译时加入 Argon2 支持时才能使用该算法。
- options 和加密算法匹配的参数项,详见 密码算法常数。
// 输出rasmuslerdorf加密后的密文 echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT); //输出:$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
- algo 加密算法
-
password_verify — 验证密码是否和散列值匹配
//生成密文 $hash = password_hash("rasmuslerdorf", PASSWORD_DEFAULT); //验证密文 if (password_verify('rasmuslerdorf', $hash)) { echo '通过验证'; } else { echo '密码错误'; }