PHP 字符串
Web 开发本质就是处理字符串——HTTP 报文、HTML、JSON、SQL 全是字符串。PHP 的字符串处理极其丰富,内置 100+ 个字符串函数。这一章重点讲单双引号差异(新手必踩的坑)和常用函数。
1. 单引号 vs 双引号(必懂!)
这是 PHP 字符串最经典、也是最容易踩坑的地方:双引号会解析变量和转义符,单引号原样输出:
<?php
$name = "小明";
// 双引号:解析变量和转义符
echo "你好,$name!"; // 你好,小明!
echo "我叫 {$name}。"; // 我叫 小明。(推荐写法)
echo "换行\n,制表\t。"; // 解析转义符
// 单引号:原样输出,不解析变量
echo '你好,$name!'; // 你好,$name!(原样)
echo '换行\n'; //
(字面反斜杠 n)
// 单引号只认识两个转义符:\\ 和 \'
echo 'It\'s me'; // It's me
// 性能:单引号略快(无需解析),但差异极小
// 建议:需要插值用双引号,纯文本用单引号几个规则:
- 双引号解析
$var这类变量,以及换行、制表等转义序列。 - 单引号几乎不解析任何东西,只有"反斜杠自身"和"单引号"两种转义。所以单引号里的反斜杠加 n 就是字面两个字符,不是换行。
- 推荐写法:插值变量时用花括号包裹(语法见下方代码块),消除歧义、可读性好。
- 性能:单引号略快(不解析),但差异微小,优先按可读性选择。
// 双引号字符串里的转义序列
echo "换行: \n"; // 换行符
echo "制表: \t"; // 制表符
echo "反斜杠: \\"; // 字面反斜杠
echo "美元: \$var"; // 字面 $var(不解析为变量)
echo "双引号: \"hi\""; // 字面双引号
// 双引号里的变量插值
$name = "小明";
echo "你好 $name"; // 你好 小明
echo "你好 {$name}"; // 你好 小明(推荐:消除歧义)
// 单引号只认两个转义:\\ 和 \'
echo '反斜杠 \\'; // 反斜杠 echo '单引号 \''; // 单引号 '2. heredoc 与 nowdoc:多行字符串
写多行字符串(HTML、SQL)时,用单双引号加换行转义太累。PHP 提供 heredoc 和 nowdoc 语法:
<?php
// heredoc:类似双引号,适合多行字符串
$html = <<<HTML
<div class="user">
<h1>{$name}</h1>
<p>欢迎</p>
</div>
HTML;
// 标识符(HTML)可以自定义,结束标识符必须顶格(PHP 7.3+ 可不顶格)
// nowdoc:类似单引号,不解析变量
$sql = <<<'SQL'
SELECT * FROM users WHERE name = ':name'
SQL;
// 注意 'SQL' 加了引号,内容里的 $name 不会解析区别:
- heredoc(
<<<NAME):类似双引号,解析变量。 - nowdoc(
<<<'NAME'):类似单引号,不解析变量。适合嵌入 SQL、代码片段。 - PHP 7.3+ 起,结束标识符可以缩进(老版本必须顶格),大大提升了可用性。
3. 字符串连接
<?php
// 字符串连接用 . (不是 +)
$greeting = "你好" . ",世界";
// 复合赋值 .=
$msg = "Hello";
$msg .= ", ";
$msg .= "World";
echo $msg; // Hello, World
// 在双引号里直接插值更方便
$name = "小明";
echo "你好,{$name}!"; // 你好,小明!
// 数组插值要加花括号
$user = ["name" => "小红"];
echo "用户:{$user['name']}"; // 用户:小红核心铁律:PHP 字符串连接用 . 不是 +。原因详见第 6 章运算符——PHP 是弱类型,+ 会把字符串转成数字相加。
4. 基础字符串函数
<?php
$s = "Hello, PHP!";
// 长度(字节数)
echo strlen($s); // 11
// 字符串长度(按字符,UTF-8 安全)
echo mb_strlen("你好"); // 2
// 截取
echo substr($s, 0, 5); // Hello
echo substr($s, -4); // PHP!
echo mb_substr("你好世界", 0, 2); // 你好
// 大小写
echo strtoupper("abc"); // ABC
echo strtolower("ABC"); // abc
echo ucfirst("hello"); // Hello(首字母大写)
echo ucwords("hello world"); // Hello World
// 查找
echo strpos($s, "PHP"); // 7
var_dump(strpos($s, "x")); // false(注意用 === 判断)
if (strpos($s, "PHP") !== false) {
echo "找到了";
}
// 替换
echo str_replace("PHP", "World", $s); // Hello, World!
echo substr_replace($s, "Hi", 0, 5); // Hi, PHP!几个易踩的坑:
- strlen 返回字节数,不是字符数。中文等多字节字符要用
mb_strlen。 - strpos 找不到返回 false,找到返回位置(可能是 0)。判断时必须用
!== false,不能用==(因为 0 会被弱等于 false)。 - substr 截中文会乱码,要用
mb_substr。所有多字节函数都在mb_前缀下。
5. trim / explode / implode
这三个是 Web 开发用得最频繁的函数:
<?php
// trim 去首尾空白(默认含空格、Tab、换行)
echo trim(" hello "); // hello
echo ltrim(" hello "); // hello
echo rtrim(" hello "); // hello
// 指定字符
echo trim("/path/", "/"); // path
echo trim("hello", "hlo"); // ell
// 重复与填充
echo str_repeat("-=", 5); // -=-=-=-=-=-
echo str_pad("5", 3, "0", STR_PAD_LEFT); // 005
// 反转
echo strrev("hello"); // olleh
// 分割与合并
$parts = explode(",", "a,b,c,d");
print_r($parts); // ["a", "b", "c", "d"]
$arr = ["x", "y", "z"];
echo implode("-", $arr); // x-y-z典型场景:
trim($_POST["name"])— 去掉用户输入的首尾空格。explode(",", $csv)— 把 CSV 字符串拆成数组。implode(", ", $tags)— 把标签数组拼成显示用字符串。
6. 字符串格式化
sprintf 是 PHP 版的 printf,用于构造格式化字符串(日志、SQL、报表):
<?php
// sprintf 格式化字符串(常见于日志、SQL)
$name = "小明";
$age = 25;
echo sprintf("姓名:%s,年龄:%d", $name, $age);
// 姓名:小明,年龄:25
// 常用占位符
sprintf("整数 %d", 42); // 整数 42
sprintf("浮点 %.2f", 3.14159); // 浮点 3.14
sprintf("字符串 %s", "hi"); // 字符串 hi
sprintf("填充 %05d", 42); // 填充 00042
sprintf("位置 %1$s 再 %1$s", "A"); // 位置 A 再 A(参数复用)
// number_format 千位分隔
echo number_format(1234567.891, 2, ".", ",");
// 1,234,567.89
// money / float 转 int
$price = (float)"99.5";sprintf 比 . 拼接可读性好得多,尤其参数多的时候。占位符和 C/Java 一致:%s 字符串、%d 整数、%f 浮点、%x 十六进制。
7. 正则表达式
PHP 用 PCRE 库,正则用 / 包裹(pattern delimiter),函数以 preg_ 开头:
<?php
// 正则匹配
if (preg_match("/^\d{4}-\d{2}-\d{2}$/", "2025-08-05")) {
echo "日期格式正确";
}
// 提取捕获组
preg_match("/(\d+)-(\d+)/", "2025-08", $m);
// $m = ["2025-08", "2025", "08"]
// 全局匹配
preg_match_all("/\d+/", "a1 b22 c333", $matches);
// $matches[0] = ["1", "22", "333"]
// 替换
$result = preg_replace("/\s+/", "-", "hello world");
// hello-world
// 邮箱正则(简单版)
$email = "test@example.com";
$isEmail = filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
// 实际项目推荐用 filter_var 而不是手写正则几个要点:
- 正则用单引号:避免 PHP 把美元符、反斜杠当成变量或转义符。如果用双引号,所有反斜杠要写两遍。
- filter_var 替代手写正则:验证邮箱、URL、IP 用内置过滤器更可靠。
- 复杂正则匹配
preg_match,全局preg_match_all,替换preg_replace(支持回调preg_replace_callback)。
8. 多字节字符串(mbstring)
PHP 默认字符串函数是字节级的,处理中文、emoji 等多字节字符会出问题。多字节扩展 mb_ 系列:
mb_strlen、mb_substr、mb_strpos— 多字节版本。mb_internal_encoding("UTF-8")— 设置默认编码。mb_convert_encoding— 编码转换(GBK ↔ UTF-8)。- 新建项目统一 UTF-8,避免乱码地狱。
小结
这一章你掌握了 PHP 字符串的核心:单双引号差异、heredoc/nowdoc、连接符、常用函数、格式化、正则、多字节。下一篇表单处理——PHP 真正的强项上场了。
← 上一篇 PHP 数组
下一篇 PHP 表单处理 →