1.5 字符串:单据文本的加工车间


文档摘要

1.5 字符串:单据文本的加工车间 本节摘要:字符串是月台上流转最广的物料——表单内容、URL 参数、日志行、响应片段全是字符串。本节先分清三种定界写法与插值规则,再过一遍拆、查、换、拼的高频函数,重点讲清多字节中文在字节与字符之间的差异,最后以"用户昵称清洗与截断"实战收尾。本节承上(1.4 的数组元素多数是字符串)启下(1.7 表单文本的校验与转义)。 先分清三种写法 PHP 里写字符串有三种常见定界方式,行为差异必须门儿清: 经验法则:纯文字、不含变量用单引号(少一层解析,意图也明确);需要插值用双引号,复杂表达式用花括号包住: 。拼接大段 HTML 时 heredoc 比一长串点号清爽得多。

1.5 字符串:单据文本的加工车间

本节摘要:字符串是月台上流转最广的物料——表单内容、URL 参数、日志行、响应片段全是字符串。本节先分清三种定界写法与插值规则,再过一遍拆、查、换、拼的高频函数,重点讲清多字节中文在字节与字符之间的差异,最后以"用户昵称清洗与截断"实战收尾。本节承上(1.4 的数组元素多数是字符串)启下(1.7 表单文本的校验与转义)。

先分清三种写法

PHP 里写字符串有三种常见定界方式,行为差异必须门儿清:

<?php $item = '行李箱'; $s1 = '一件$item'; // 单引号:原样输出,不做插值 echo $s1, "\n"; // 一件$item $s2 = "一件$item"; // 双引号:解析变量与转义符 echo $s2, "\n"; // 一件行李箱 $s3 = <<<TXT 托运单:{$item}x1 备注:易碎品,轻拿轻放 TXT; // heredoc:同双引号规则,适合多行 echo $s3, "\n";

经验法则:纯文字、不含变量用单引号(少一层解析,意图也明确);需要插值用双引号,复杂表达式用花括号包住:"共{$count}件"。拼接大段 HTML 时 heredoc 比一长串点号清爽得多。

拆、查、换、拼:高频函数过一遍

围绕一个示例串演示,注释即输出:

<?php $line = ' G102,南苑,虹桥,08:30 '; // 查与取 echo strpos($line, '虹桥'), "\n"; // 位置(字节偏移),找不到返回 false echo substr($line, 2, 4), "\n"; // G102(按下标截取) // 换与修 echo trim($line), "\n"; // 去首尾空白:G102,南苑,虹桥,08:30 echo str_replace('南苑', '西站', $line), "\n"; // 拆与拼 $parts = explode(',', trim($line)); // 按分隔符拆成数组 print_r($parts); // [G102, 南苑, 虹桥, 08:30] echo implode(' | ', $parts), "\n"; // 反向拼回字符串 // 格式化 echo sprintf('%s 次列车 %s 发车,票价 %.2f 元', $parts[0], $parts[3], 55.5), "\n"; // G102 次列车 08:30 发车,票价 55.50 元

sprintf 值得多花两条命令练熟:%s 填字符串、%d 填整数、%.2f 控小数位,模板与数据分离,比一长串点号拼接好读得多。

字节与字符:中文的门道

这是本节的重心。PHP 的字符串本质是字节序列,strlen 数的是字节;一个 UTF-8 汉字占三个字节,于是出现了"函数说有六、肉眼只有两"的错位。凡涉及中文,一律换 mb_ 前缀的多字节函数:

<?php $nick = '月台客'; var_dump(strlen($nick)); // int(9):三个汉字共九字节 var_dump(mb_strlen($nick)); // int(3):三个字符 var_dump(substr($nick, 0, 4)); // 可能切出半个汉字,输出乱码 var_dump(mb_substr($nick, 0, 2)); // 月台:按字符切,安全

乱码问题还要守住另外两端:文件本身以 UTF-8 无签名编码保存,响应头声明 Content-Type: text/html; charset=utf-8(2.3 节展开)。三端一致(源码端、处理端、输出端),中文问题基本绝迹;任何一端不一致,都会以"页面上问号或火星文"的形式收场。大小写转换同理:strtolower 对中文无意义,对带音标的西文也不完整,需要时用 mb_strtolower

实战:用户昵称的清洗与截断

把本节函数组装成一条完整的加工线。场景:旅客注册填写昵称,要求去掉首尾空白、压掉连续空格、过滤敏感标记、超长按字符截断,并保证截断后仍可安全输出到 HTML:

<?php function cleanNickname(string $raw, int $maxChars = 12): string { $nick = trim($raw); // 去首尾空白 $nick = preg_replace('/\s+/u', ' ', $nick); // 连续空白压成一个空格 $nick = strip_tags($nick); // 拍掉内嵌的 HTML 标签 if (mb_strlen($nick) > $maxChars) { $nick = mb_substr($nick, 0, $maxChars) . '…'; } return $nick; } echo cleanNickname(' 张 三 <b>速达</b>旅客们请注意' ), "\n"; // 张 三 速达旅客们请注… (按字符截断,无乱码)

走一遍流程解读:trim 收边、正则压空格、strip_tags 拆掉伪装成昵称的标签、超长按 mb_ 截断补省略号。输出到页面时还要过一道 htmlspecialchars(1.7 节专门讲),那是出站前的最后一道安检,与本节的入库前清洗分工不同、缺一不可。变式:若产品要求昵称唯一,清洗后还需按规范化结果查重,规范化函数定下来就别再改,否则历史数据对不上。

变式思路:如果昵称要参与唯一性判断(一个昵称只能一位旅客使用),清洗函数之外还需要一道"规范化"——统一全半角、统一大小写规则后再比对,而且规范化规则一旦上线就不能再改,否则历史数据之间对不上号。这类"格式资产"的设计决策,比函数本身更值得在动手前想清楚。另外补一个"字符与显示宽度"的边界提醒:字符数对了,显示宽度未必对——等宽终端里一个汉字通常占两个英文字符的位置,做命令行表格、对齐输出时要用"显示宽度"而非"字符数"来补空格,否则表格永远对不齐。这类细节不影响正确性,但决定交付物的体面程度。另外提醒一处性能分寸:preg_replace 与多字节函数都比基础函数慢,但它们工作在"每请求个位次数"的量级,完全不必为省这点开销牺牲正确性——真正要计较的是 2.5 节那种循环千次的场景。

常见问题

为什么 strlen 统计中文数量不对?

strlen 统计字节数,UTF-8 下一个汉字占三个字节,所以结果约是字符数的三倍。统计字符请用 mb_strlen,截取请用 mb_substr,并把多字节扩展确认在已加载清单里(1.1 节的 php -m)。

本节要点回顾

  • 定界三式:单引号不插值,双引号与 heredoc 插值,模板复杂度决定选哪种。
  • 加工四件套:explode 与 implode 管拆拼,str_replace 管替换,sprintf 管格式化。
  • 中文必用多字节函数mb_strlenmb_substr 替换字节版函数,三端编码统一 UTF-8。
  • 清洗有次序:收边、压空白、去标签、按字符截断,顺序固定成习惯。

下一节转向文件与目录:字符串要落成日志与配置,就得经过站内仓库的手。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U