# PHP字符串截取:substr() 和 mb_substr() 的正确使用
在PHP开发中,字符串截取是最常见的操作之一。然而,如果不了解不同函数间的区别,很容易在处理多字节字符(如中文)时出现问题。今天我们就来深入探讨PHP中两个核心字符串截取函数:substr()和mb_substr()。
## substr()函数的基本用法
substr()是PHP内置的字符串截取函数,其基本语法为:
```php
substr(string $string, int $start, ?int $length = null): string
```
**参数说明:**
- `$string`:要截取的原始字符串
- `$start`:起始位置(负数表示从末尾开始)
- `$length`(可选):要截取的长度(负数表示去掉末尾若干个字符)
**示例代码:**
```php
$str = "Hello, World!";
echo substr($str, 0, 5); // 输出: Hello
echo substr($str, 7); // 输出: World!
echo substr($str, -6, 5); // 输出: World
```
## substr()的局限性
substr()在处理ASCII字符时表现良好,但在处理多字节字符(如中文、日文等)时会出现问题:
```php
$chinese = "你好,世界!";
echo substr($chinese, 0, 2); // 可能输出乱码或不完整字符
```
这是因为substr()是按字节(byte)而不是按字符(character)进行截取。一个中文字符在UTF-8编码下通常占3个字节,截取2个字节会导致不完整字符。
## mb_substr()函数介绍
mb_substr()是mbstring扩展提供的多字节安全字符串截取函数,其语法与substr()类似:
```php
mb_substr(string $string, int $start, ?int $length = null, ?string $encoding = null): string
```
**关键区别:**
- 第四个参数`$encoding`可以指定字符编码
- 按字符而不是字节进行截取
**示例代码:**
```php
$chinese = "你好,世界!";
echo mb_substr($chinese, 0, 2, 'UTF-8'); // 正确输出: 你好
```
## 何时使用哪个函数
1. **使用substr()的场景:**
- 处理纯ASCII字符串(英文、数字、标点)
- 需要高性能的简单截取操作
- 确定字符串不会包含多字节字符
2. **必须使用mb_substr()的场景:**
- 处理包含中文、日文、韩文等多字节字符的字符串
- 不确定字符串编码但需要安全截取
- 需要按字符数精确截取(如限制标题长度)
## 实用技巧分享
### 1. 安全截取UTF-8字符串函数
```php
function safe_substr($str, $start, $length = null) {
if (function_exists('mb_substr')) {
return mb_substr($str, $start, $length, 'UTF-8');
}
return substr($str, $start, $length); // 退而求其次
}
```
### 2. 截取并保留完整字符
```php
$text = "这是一段测试文本,用于演示截取功能";
$maxLength = 10;
if (mb_strlen($text, 'UTF-8') > $maxLength) {
$text = mb_substr($text, 0, $maxLength, 'UTF-8') . '...';
}
```
### 3. 处理HTML内容截取
```php
function html_substr($html, $start, $length) {
$text = strip_tags($html); // 先去除HTML标签
return mb_substr($text, $start, $length, 'UTF-8');
}
```
## 性能考量
substr()是PHP内置函数,性能优于mb_substr()。在对性能要求极高的场景下,如果确定不会有多字节字符,优先使用substr()。
## 常见问题解答
**Q:为什么mb_substr()有时会报错?**
A:通常是因为未安装或未启用mbstring扩展。可以通过php.ini中启用或使用`extension_loaded('mbstring')`检查。
**Q:如何获取多字节字符串的长度?**
A:使用`mb_strlen($str, 'UTF-8')`而不是strlen()。
**Q:如何处理不同编码的字符串?**
A:始终明确指定编码参数,如'UTF-8'、'GB2312'等,避免因服务器默认编码不同导致问题。
## 总结
正确选择字符串截取函数是保证PHP应用国际化支持的关键。记住:
- ASCII字符:substr()足够
- 多字节字符:必须使用mb_substr()
- 不确定时:优先使用mb_substr()
掌握这两个函数的使用场景和区别,能让你在处理字符串时更加得心应手,避免出现乱码或截取不完整的问题。