北海网站设计公司网络营销专业课
PHP字符串操作
一,字符串定义语法
1. 单引号字符串(Single-Quoted Strings)
语法
$str = '这是一个单引号字符串';
 
特点
-  
不解析变量
单引号内的内容会被原样输出,变量和转义字符(除\\和\'外)不会被处理。$name = "PHP"; echo 'Hello, $name!'; // 输出:Hello, $name! -  
支持的转义符
仅支持两种转义:\\→ 反斜杠\'→ 单引号
echo '路径:C:\\xampp\\htdocs'; // 输出:路径:C:\xampp\htdocs -  
性能优势
由于无需解析变量和复杂转义,单引号字符串在无变量时性能略优。 
2. 双引号字符串(Double-Quoted Strings)
语法
$str = "这是一个双引号字符串";
 
特点
-  
解析变量
直接嵌入变量名,变量值会被替换:$fruit = "apple"; echo "I like $fruit!"; // 输出:I like apple! -  
复杂变量语法
使用{}明确变量边界,避免歧义:$type = "果汁"; echo "这是{$type}的瓶子"; // 输出:这是果汁的瓶子 -  
支持丰富的转义字符
转义符包括:\n→ 换行\t→ 制表符\"→ 双引号\$→ 美元符号\x1A→ 十六进制 ASCII 字符
echo "第一行\n第二行\t制表符"; 
3. Heredoc 结构(多行字符串)
语法
$str = <<<EOD
多行内容
可以包含变量和转义符
EOD;
 
规则
-  
标识符命名
必须遵循变量命名规则(字母、数字、下划线,不能以数字开头),常用EOD、EOF等。 -  
结束标记
必须单独一行、顶格书写,且以分号结束:// 正确 $html = <<<HTML <div><p>$content</p> </div> HTML;// 错误!结束标记缩进 $html = <<<HTML <div></div>HTML; -  
行为类似双引号字符串
解析变量和转义符,适合嵌入 HTML 模板或长文本:$user = "Alice"; echo <<<MSG 欢迎,$user! 您的订单已确认。 MSG; 
4. Nowdoc 结构(单引号多行字符串)
语法
$str = <<<'EOD'
内容不解析变量和转义符(除 \\ 和 \')
EOD;
 
规则
-  
标识符需单引号包裹
<<<'EOD'表示 Nowdoc 结构。 -  
行为类似单引号字符串
变量和转义符(如\n)不会被处理:$count = 10; echo <<<'TEXT' 当前计数:$count\n TEXT; // 输出:当前计数:$count\n 
变量解析的详细规则
简单语法
直接写变量名,适用于变量后无歧义字符:
$drink = "coffee";
echo "I need $drink!"; // 输出:I need coffee!
 
复杂语法(花括号)
通过 {} 明确变量边界:
-  
避免歧义
$var = "cat"; echo "这是${var}s"; // 输出:这是cats -  
解析数组或对象属性
$arr = ["key" => "value"]; echo "数组值:{$arr['key']}"; // 输出:数组值:value -  
动态变量名
$prop = "name"; echo "属性是:${$prop}"; // 等价于 $name 
实际应用场景
-  
单引号
-  
静态文本(如配置键名)
 -  
无需转义的简单路径:
$path = 'C:\xampp\htdocs\file.txt'; 
 -  
 -  
双引号
-  
含变量或转义符的动态文本:
$error = "404"; echo "错误代码:$error\n请检查输入。"; 
 -  
 -  
Heredoc
-  
多行 HTML 模板:
$html = <<<HTML <table><tr><td>$username</td></tr> </table> HTML; 
 -  
 -  
Nowdoc
-  
保留原始格式的文档(如 SQL 语句):
$sql = <<<'SQL' SELECT * FROM users WHERE id = 1; SQL; 
 -  
 
注意事项
- 性能差异
单引号/Nowdoc 在无变量时略快,但差异可忽略不计,优先考虑代码可读性。 - 转义字符优先级
双引号中的\$表示字面量$,而单引号中的\'表示单引号。 - 多行字符串缩进
Heredoc/Nowdoc 的内容可以缩进,但结束标记必须顶格。 
错误示例与修正
错误:Heredoc 结束标记未顶格
// 错误!
$str = <<<EOD内容...EOD;
 
修正:
$str = <<<EOD
内容...
EOD;
 
二,字符串的转义符
1. 单引号字符串的转义
单引号字符串仅支持两种转义,其他字符前的反斜杠会被原样输出:
\\→ 表示单个反斜杠\\'→ 表示单引号'
示例:
echo '路径:C:\\xampp\\htdocs'; // 输出:路径:C:\xampp\htdocs
echo '这是一个单引号:\'';      // 输出:这是一个单引号:'
echo '换行符\n不会被转义';      // 输出:换行符\n不会被转义
 
2. 双引号字符串的转义
双引号字符串支持丰富的转义字符,包括:
| 转义符 | 含义 | 
|---|---|
\" | 双引号 " | 
\\ | 反斜杠 \ | 
\$ | 美元符号 $(避免变量解析) | 
\n | 换行符(ASCII 10) | 
\r | 回车符(ASCII 13) | 
\t | 水平制表符(Tab) | 
\v | 垂直制表符 | 
\e | Escape 键(ASCII 27) | 
\f | 换页符(ASCII 12) | 
\xHH | 十六进制 ASCII 字符(如 \x1A) | 
\u{XXXX} | Unicode 字符(如 \u{1F600} 表示😀) | 
示例:
echo "双引号:\",换行符:\n,制表符:\t,美元符号:\$"; 
// 输出:
// 双引号:",换行符:
// ,制表符:    ,美元符号:$
 
3. Heredoc 结构的转义
Heredoc 的行为与双引号字符串一致,支持双引号的所有转义规则,同时允许直接嵌入变量。
示例:
$var = "World";
echo <<<EOD
Hello, $var!\n转义符:\t、\x40(@)、\u{2665}(♥)
EOD;
// 输出:
// Hello, World!
// 转义符:    、@、♥
 
4. Nowdoc 结构的转义
Nowdoc 的行为与单引号字符串一致,仅支持两种转义:
\\→ 反斜杠\\'→ 单引号'(但 Nowdoc 本身用单引号包裹标识符,内部单引号无需转义)
示例:
echo <<<'EOT'
这是一个 Nowdoc 字符串:
反斜杠:\\,单引号:',换行符\n原样输出。
EOT;
// 输出:
// 这是一个 Nowdoc 字符串:
// 反斜杠:\,单引号:',换行符\n原样输出。
 
常见场景与注意事项
场景 1:输出字面量 $ 或 "
 
在双引号字符串中,若需输出 $ 或 ",必须转义:
echo "价格:\$100";     // 输出:价格:$100
echo "引号:\"";        // 输出:引号:"
 
场景 2:多行文本中的转义
Heredoc 适合编写多行文本并保留转义效果:
echo <<<XML
<root><node>\t内容</node>  <!-- 转义为制表符 -->
</root>
XML;
 
场景 3:动态生成正则表达式
需转义正则符号(如 / 或 \):
$pattern = "/^\\d+$/"; // 等价于 "/^\d+$/"
 
错误示例:
// 错误!未转义 $,导致解析变量
echo "价格:$100";     // 尝试解析变量 $100(未定义)// 正确写法:
echo "价格:\$100";    // 输出:价格:$100
 
总结表
| 字符串类型 | 支持的转义符 | 
|---|---|
| 单引号 | \\, \' | 
| 双引号 | \", \\, \$, \n, \r, \t, \xHH, \u{XXXX} 等 | 
| Heredoc | 同双引号 | 
| Nowdoc | 同单引号 | 
最佳实践
- 优先单引号:当无需变量解析和复杂转义时,使用单引号提高可读性和性能。
 - 明确变量边界:在双引号或 Heredoc 中,用 
{}包裹变量名(如"{$var}")。 - 避免过度转义:在单引号字符串中,除了 
\\和\',其他反斜杠无需转义。 
三,字符串长度
在 PHP 中,字符串长度的处理与字符编码密切相关,尤其是在处理多字节字符(如中文、Emoji 等)时需要注意细节。以下是字符串长度相关知识的详细说明:
1. 获取字符串长度的函数
PHP 提供了两个常用函数来获取字符串长度:
strlen()
返回字符串的字节数(基于当前字符编码)。mb_strlen()
返回字符串的字符数(需指定字符编码,正确处理多字节字符)。
示例对比:
$str = "Hello, 世界!"; // 包含英文和中文// 使用 strlen():按字节计算
echo strlen($str); 
// 输出:13(英文占1字节/字符,中文UTF-8占3字节/字符)
// 计算方式:7 (Hello,) + 3*2 (世界) + 3 (!) = 7 + 6 + 3 = 16? 可能需要验证实际字节数// 使用 mb_strlen():按字符计算
echo mb_strlen($str, 'UTF-8'); 
// 输出:9(H, e, l, l, o, ,, 空, 世, 界, !)
 
2. 字符编码对长度的影响
- 单字节编码(如 ASCII)
strlen()和mb_strlen()结果相同,因为每个字符占1字节。 - 多字节编码(如 UTF-8) 
- 中文、日文等字符在 UTF-8 中通常占 3~4 字节。
 - Emoji 字符(如 😊)可能占 4 字节。
 - 使用 
strlen()会返回字节数,而mb_strlen()返回实际字符数。 
 
示例:
$emoji = "😊";
echo strlen($emoji);      // 输出:4(UTF-8 编码)
echo mb_strlen($emoji, 'UTF-8'); // 输出:1
 
3. 处理多字节字符串的注意事项
(1) 截取子字符串
-  
错误方式:直接使用
substr()
可能截断多字节字符,导致乱码。$str = "你好,世界!"; echo substr($str, 0, 5); // 输出乱码:你�(UTF-8 中每个中文占3字节) -  
正确方式:使用
mb_substr()
指定编码后安全截取。echo mb_substr($str, 0, 2, 'UTF-8'); // 输出:你好 
(2) 遍历字符串字符
-  
错误方式:直接按字节循环
使用strlen()+ 下标访问可能拆分多字节字符。$str = "测试"; for ($i = 0; $i < strlen($str); $i++) {echo $str[$i]; // 输出乱码:拆分成3个字节 } -  
正确方式:使用
mb_strlen()+mb_substr()$length = mb_strlen($str, 'UTF-8'); for ($i = 0; $i < $length; $i++) {echo mb_substr($str, $i, 1, 'UTF-8'); // 输出:测 试 } 
4. 字符串的最大长度
- 理论限制
PHP 字符串的长度受内存限制,由memory_limit配置决定。 - 实际限制
通常单字符串可达几百 MB 甚至几 GB(取决于可用内存),但超大字符串会影响性能。 
5. 性能优化
strlen()是 O(1) 操作
PHP 内部记录字符串的字节长度,strlen()直接返回预存值,速度极快。mb_strlen()是 O(n) 操作
需要遍历字符串计算字符数,性能较低(尤其是大字符串)。
6. 常见问题与解决方案
问题 1:中文字符长度计算错误
$str = "你好";
echo strlen($str); // 输出:6(UTF-8 下每个中文占3字节)
// 期望字符数为2,需用 mb_strlen()
 
问题 2:字符串截断乱码
$str = "Hello, 世界!";
echo substr($str, 0, 7); // 输出:Hello, �(第7字节位于中文字符中间)
// 正确方式:mb_substr($str, 0, 7, 'UTF-8')
 
问题 3:未设置默认编码导致错误
// 需先设置默认编码(或在函数中显式指定)
mb_internal_encoding('UTF-8');
echo mb_strlen("测试"); // 正确输出:2
 
7. 最佳实践
-  
统一使用 UTF-8 编码
在文件、数据库、HTTP 头中明确使用 UTF-8。 -  
多字节操作使用
mb_\*函数
如mb_strlen(),mb_substr(),mb_strpos()。 -  
始终指定编码参数
避免依赖服务器默认配置:mb_strlen($str, 'UTF-8'); 
7. 最佳实践
-  
全局设置默认编码
在脚本开头设置:mb_internal_encoding('UTF-8'); mb_http_output('UTF-8'); -  
优先使用
mb_\*函数处理多字节文本
替代原生函数如strlen、substr。 -  
验证输入数据的编码
使用mb_check_encoding()确保数据符合预期编码:if (!mb_check_encoding($input, 'UTF-8')) {// 处理非法编码 } 
总结表
| 场景 | 推荐函数/方法 | 说明 | 
|---|---|---|
| 获取字节数 | strlen() | 快速,但不处理多字节字符 | 
| 获取字符数 | mb_strlen($str, 'UTF-8') | 需指定编码 | 
| 截取子字符串 | mb_substr($str, $start, $length, 'UTF-8') | 安全处理多字节字符 | 
| 遍历字符串 | mb_strlen() + mb_substr() | 避免拆分多字节字符 | 
四,mbstring扩展
PHP 的 mbstring 扩展(Multibyte String Extension)是专门用于处理多字节字符(如中文、日文、韩文、Emoji 等)的核心扩展。它提供了一系列函数,用于安全操作多字节编码的字符串(如 UTF-8、GBK、Big5 等),避免因直接使用原生字符串函数导致的乱码或逻辑错误。
1. mbstring 扩展是什么
 
-  
多字节字符问题
像 UTF-8 这样的编码中,一个字符可能占用多个字节(如中文占 3 字节,Emoji 占 4 字节)。
原生函数(如strlen、substr)按字节操作,可能拆分多字节字符,导致乱码。$str = "你好"; echo strlen($str); // 输出 6(字节数),而非字符数 2 echo substr($str, 0, 2); // 输出乱码(截断第一个中文字符的中间字节) -  
mbstring的作用
提供mb_strlen、mb_substr等函数,按字符(而非字节)处理字符串,确保操作安全。 
2. 安装与启用 mbstring
 
安装方式
-  
Linux (Ubuntu/Debian)
通过包管理器安装:sudo apt-get install php-mbstring -  
Windows
在php.ini中取消注释以下行:extension=mbstring -  
通用方法(源码编译)
编译 PHP 时添加--enable-mbstring参数。 
验证安装
运行 php -m | grep mbstring 或创建 PHP 文件:
<?php
var_dump(extension_loaded('mbstring')); // 输出 bool(true) 表示成功
 
3. 核心功能与常用函数
(1) 设置默认编码
-  
mb_internal_encoding()
设置脚本内部默认编码(需与其他环节编码一致,如数据库、HTTP 头)。mb_internal_encoding('UTF-8'); // 推荐全局设置 
(2) 字符串长度与截取
-  
mb_strlen()
获取字符串的字符数(而非字节数):$str = "Hello, 世界!"; echo mb_strlen($str, 'UTF-8'); // 输出 9(字符数) -  
mb_substr()
安全截取子字符串:$str = "你好,世界!"; echo mb_substr($str, 0, 2, 'UTF-8'); // 输出 "你好" 
(3) 字符串位置与替换
-  
mb_strpos()
查找字符位置(按字符而非字节):$pos = mb_strpos("abcdef", "d", 0, 'UTF-8'); // 返回 3 -  
mb_str_replace()
多字节安全的字符串替换:echo mb_str_replace("世界", "PHP", "你好,世界!", 'UTF-8'); // 输出 "你好,PHP!" 
(4) 大小写转换
-  
mb_strtolower()/mb_strtoupper()
支持多字节字符的大小写转换:echo mb_strtoupper("abc Déjà", 'UTF-8'); // 输出 "ABC DÉJÀ" 
(5) 编码转换
-  
mb_convert_encoding()
转换字符串编码(如 UTF-8 → GBK):$str = "你好"; $gbk_str = mb_convert_encoding($str, 'GBK', 'UTF-8'); 
4. 常见应用场景
场景 1:处理表单输入
确保接收到的多字节数据(如中文用户名)正确处理:
// 设置接收编码为 UTF-8
mb_http_input('UTF-8');
mb_language('uni');
 
场景 2:数据库交互
统一数据库连接编码,避免乱码:
// PDO 示例
$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", "user", "pass");
 
场景 3:文件读写
读取或写入多字节文本文件时指定编码:
$content = file_get_contents("data.txt");
$content = mb_convert_encoding($content, 'UTF-8', 'SJIS'); // 转换日文编码
 
5. 注意事项
(1) 编码一致性
- 始终明确指定编码参数(如 
mb_substr($str, 0, 2, 'UTF-8')),避免依赖默认配置。 - 确保文件存储、数据库、HTTP 头等环节使用统一编码(推荐 UTF-8)。
 
(2) 性能优化
mb_*函数比原生函数略慢,但多数场景差异可忽略。- 超大字符串处理时,避免频繁调用 
mb_*函数。 
(3) 错误处理
-  
编码转换失败时,
mb_convert_encoding可能返回false或乱码:$str = mb_convert_encoding($invalidStr, 'UTF-8', 'GBK'); if ($str === false) {throw new Exception("编码转换失败"); } 
6. 常见问题与解决
问题 1:未启用 mbstring 扩展
 
- 表现:调用 
mb_strlen时报错Call to undefined function。 - 解决:安装并启用 
mbstring扩展。 
问题 2:编码不一致导致乱码
-  
表现:字符串显示为问号
�或乱码。 -  
解决:检查并统一各环节编码,使用
mb_detect_encoding检测实际编码:$encoding = mb_detect_encoding($str, ['UTF-8', 'GBK', 'BIG5']); 
问题 3:函数参数缺失编码
-  
错误示例:
echo mb_strlen("你好"); // 未指定编码,可能返回错误值 -  
解决:始终传递编码参数:
echo mb_strlen("你好", 'UTF-8'); 
五,字符串相关函数
一、字符串基础操作
1. 字符串长度
-  
strlen(string $str): int
返回字符串的字节数(非字符数,不适用于多字节字符)。echo strlen("Hello"); // 输出:5 -  
mb_strlen(string $str, string $encoding = null): int
返回字符串的字符数(需指定编码处理多字节字符)。echo mb_strlen("你好", "UTF-8"); // 输出:2 
2. 字符串拼接
-  
.运算符
直接连接多个字符串。$str = "Hello" . " " . "World"; // "Hello World" -  
implode(string $glue, array $pieces): string
将数组元素拼接为字符串,用指定分隔符连接。echo implode(", ", ["Apple", "Banana"]); // "Apple, Banana" 
3. 字符串分割
-  
explode(string $separator, string $str, int $limit = PHP_INT_MAX): array
按分隔符拆分字符串为数组。$arr = explode(" ", "a b c"); // ["a", "b", "c"] -  
preg_split(string $pattern, string $str): array
使用正则表达式分割字符串。$arr = preg_split("/[\s,]+/", "a,b c"); // ["a", "b", "c"] 
二、字符串搜索与替换
1. 查找子字符串
-  
strpos(string $haystack, string $needle): int|false
返回子字符串首次出现的字节位置(区分大小写)。echo strpos("Hello World", "Wo"); // 6 -  
str_contains(string $haystack, string $needle): bool(PHP 8+)
判断字符串是否包含子字符串。echo str_contains("PHP", "H"); // true 
2. 替换内容
-  
str_replace(array|string $search, array|string $replace, string $str): string
替换字符串中的指定内容。echo str_replace("World", "PHP", "Hello World"); // "Hello PHP" -  
preg_replace(string $pattern, string $replacement, string $str): string
使用正则表达式替换。echo preg_replace("/\d+/", "X", "a1b2"); // "aXbX" 
三、字符串格式化
1. 大小写转换
-  
strtolower(string $str): string
转换为全小写。echo strtolower("HELLO"); // "hello" -  
strtoupper(string $str): string
转换为全大写。echo strtoupper("hello"); // "HELLO" -  
ucwords(string $str): string
每个单词首字母大写。echo ucwords("hello world"); // "Hello World" 
2. 去除空白字符
-  
trim(string $str, string $chars = " \t\n\r\0\x0B"): string
去除字符串两端的空白或指定字符。echo trim(" text "); // "text" -  
ltrim()/rtrim()
分别去除左端或右端字符。 
3. 格式化输出
-  
sprintf(string $format, mixed ...$values): string
格式化字符串(类似 C 语言printf)。echo sprintf("Name: %s, Age: %d", "Alice", 30); // "Name: Alice, Age: 30" 
四、子字符串操作
1. 截取子字符串
-  
substr(string $str, int $start, int $length = null): string
按字节截取子字符串(可能破坏多字节字符)。echo substr("Hello", 1, 3); // "ell" -  
mb_substr(string $str, int $start, int $length, string $encoding): string
安全截取多字节字符的子字符串。echo mb_substr("你好世界", 0, 2, "UTF-8"); // "你好" 
2. 提取特定内容
-  
strstr(string $haystack, string $needle, bool $before_needle = false): string|false
返回从子字符串首次出现到结尾的部分。echo strstr("user@example.com", "@"); // "@example.com" 
五、编码与转义
1. URL 编码
-  
urlencode(string $str): string
对字符串进行 URL 编码。echo urlencode("a b=c"); // "a%20b%3Dc" -  
urldecode(string $str): string
解码 URL 编码的字符串。 
2. HTML 转义
-  
htmlspecialchars(string $str, int $flags = ENT_QUOTES): string
将特殊字符转换为 HTML 实体。echo htmlspecialchars("<a>link</a>"); // "<a>link</a>" 
3. 多字节编码转换
-  
mb_convert_encoding(string $str, string $to_encoding, string $from_encoding): string
转换字符串编码(如 UTF-8 → GBK)。$gbk_str = mb_convert_encoding("你好", "GBK", "UTF-8"); 
六、哈希与加密
1. 哈希计算
-  
md5(string $str, bool $raw_output = false): string
计算字符串的 MD5 哈希值。echo md5("password"); // "5f4dcc3b5aa765d61d8327deb882cf99" -  
sha1(string $str): string
计算 SHA1 哈希值。 
2. 密码安全
-  
password_hash(string $password, string $algorithm): string
生成密码的哈希值(推荐使用PASSWORD_DEFAULT算法)。$hash = password_hash("123456", PASSWORD_DEFAULT); 
七、正则表达式
1. 匹配与提取
-  
preg_match(string $pattern, string $str, array &$matches): int
执行正则表达式匹配。preg_match("/\d+/", "ID: 123", $matches); echo $matches[0]; // "123" 
2. 全局匹配
-  
preg_match_all(string $pattern, string $str, array &$matches): int
匹配所有符合条件的结果。preg_match_all("/\d+/", "a1 b2", $matches); print_r($matches[0]); // ["1", "2"] 
八、注意事项与最佳实践
- 多字节字符处理
涉及中文、Emoji 等时,优先使用mb_*函数(如mb_substr、mb_strlen)。 - 避免 SQL 注入
使用预处理语句(如 PDO)而非手动拼接 SQL,或至少用mysqli_real_escape_string转义。 - 性能优化
正则表达式(preg_*)性能较低,简单操作优先用原生函数(如str_replace)。 - 编码一致性
确保文件、数据库、HTTP 头的编码统一(推荐 UTF-8)。 
总结示例
// 安全处理用户输入
$input = trim($_POST["username"]);
$input = htmlspecialchars($input, ENT_QUOTES, "UTF-8");// 多字节字符串截取
$text = "你好,世界!";
$sub = mb_substr($text, 0, 2, "UTF-8"); // "你好"// 正则提取邮箱
preg_match("/[\w\.-]+@[\w\.-]+/", "Contact: user@example.com", $matches);
echo $matches[0]; // "user@example.com"
