php面试高频题,考察数组操作与字符串遍历;基础实现用foreach遍历字符,以关联数组记录频次,需注意空字符串、中文字符等边界处理。

统计字符串中每个字符出现的次数,是 PHP 面试中高频基础题,考察对数组操作、字符串遍历、边界处理的理解,不难但容易忽略细节。
基础实现:foreach + 字符计数
最直观的方式是遍历字符串每个字符,用关联数组记录频次:
function charFrequency($str) {
$freq = [];
for ($i = 0; $i < strlen($str); $i++) {
$char = $str[$i];
if (isset($freq[$char])) {
$freq[$char]++;
} else {
$freq[$char] = 1;
}
}
return $freq;
}
- 注意:PHP 中字符串支持下标访问(如 $str[0]),但需确保是单字节编码(如 ASCII);若含中文等多字节字符,strlen 和下标访问会出错
- 推荐用 str_split($str, 1) 或 mb_str_split($str)(PHP 7.4+)安全拆分字符
兼容多字节字符:用 mb_ 系列函数
处理中文、emoji 等 UTF-8 字符必须使用多字节函数:
function charFrequencyUtf8($str) {
$freq = [];
$chars = mb_str_split($str); // PHP 7.4+
// 或兼容旧版:$chars = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY);
foreach ($chars as $char) {
$freq[$char] = ($freq[$char] ?? 0) + 1;
}
return $freq;
}
- mb_str_split 是最简洁安全的选择;若版本低于 7.4,可用 preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY)
- 避免用 str_split($str) 处理中文——它按字节切分,一个汉字会被拆成多个乱码片段
进阶优化:忽略空格/大小写/非字母数字
面试常追加需求,例如“只统计英文字母,忽略大小写”:
立即学习“PHP免费学习笔记(深入)”;
function charFrequencyAlpha($str) {
$freq = [];
$chars = mb_str_split(strtolower($str)); // 统一小写
foreach ($chars as $char) {
if (ctype_alpha($char)) { // 只保留字母
$freq[$char] = ($freq[$char] ?? 0) + 1;
}
}
// 按频次降序,频次相同时按字母升序
uasort($freq, function($a, $b) {
if ($a !== $b) return $b <=> $a;
return strcmp(key($freq), key($freq)); // 实际需额外处理键排序
});
// 更稳妥:先 ksort 再 uasort,或 array_multisort
return $freq;
}
- 常用过滤函数:ctype_alpha()(字母)、ctype_alnum()(字母数字)、ctype_lower() 等
- 排序建议:先用 ksort() 按字符排序,再用 uasort() 按值降序;或用 array_multisort(array_values($freq), SORT_DESC, $freq)
常见陷阱与面试加分点
写出正确代码只是起点,面试官更关注你是否考虑周全:
- 空字符串/NULL 输入:应提前判断并返回空数组,避免警告
- 性能意识:strlen() 在循环条件中每次调用?应提前存为变量;foreach 比 for 更适合遍历数组
- 键名安全性:用户输入的字符可能含不可见控制符(如 \0、\r),可选是否过滤(如用 ctype_print())
- 扩展性提示:可提“封装为类,支持自定义过滤器、排序策略”,体现设计意识











