ucwords仅处理ASCII小写字母,对大写、数字、中文、emoji等不转换;需用mb_convert_case处理UTF-8多字节字符;支持自定义分隔符但不支持正则;只接受字符串参数,数组需配合array_map使用。

ucwords只处理ASCII小写字母,大写或非ASCII字符不会被转换
直接调用 ucwords("HELLO WORLD") 会原样返回 "HELLO WORLD",因为该函数只对 ASCII 范围内 a-z(0x61–0x7a)的首字符做转换;遇到已大写、数字、中文、emoji 或 UTF-8 多字节字符,一律跳过。这不是 bug,是 PHP 8.2+ 的明确行为——它已彻底脱离 setlocale() 影响,只认纯 ASCII。
常见错误现象:ucwords("café") → "Café"(é 不变),ucwords("张三 李四") → "张三 李四"(中文无变化)。
如果你要处理带重音符号的西文或中文姓名,必须先用 mb_convert_case($str, MB_CASE_TITLE, 'UTF-8') 替代。
自定义分隔符才能正确处理下划线、竖线等非空格分隔场景
默认情况下,ucwords 只识别空格、制表符、换行等空白字符作为单词边界。遇到 "first_name" 或 "hello|world" 这类字符串,它会把整个串当一个“单词”,只转首字母:ucwords("first_name") → "First_name"。
立即学习“PHP免费学习笔记(深入)”;
解决方法是传入第二个参数 $separators:
-
ucwords("first_name", "_")→"First_Name" -
ucwords("mike o'hara", " \t\r\n\f\v'")→"Mike O'Hara"(加单引号进分隔符列表) -
ucwords("user-id-email", "-")→"User-Id-Email"
注意:分隔符必须是字符串,不能是正则;多个分隔符需全部显式列出,比如同时支持下划线和中划线就得写 "_-" 。
数组批量处理时别直接套用,得配合 foreach 或 array_map
ucwords 只接受字符串,不支持数组。写成 ucwords(["apple", "banana"]) 会报 Warning: ucwords() expects parameter 1 to be string。
正确做法是逐个处理:
- 用
array_map('ucwords', $array)最简洁 - 或手动
foreach:$names = ["john doe", "jane smith"]; $titles = []; foreach ($names as $name) { $titles[] = ucwords($name); }
如果数组里混有 null 或数字,建议先过滤:array_map(fn($s) => is_string($s) ? ucwords($s) : $s, $array)。
和 ucfirst、mb_convert_case 的关键区别在哪
容易混淆的三个函数:
-
ucfirst("hello world")→"Hello world"(只动第一个字符) -
ucwords("hello world")→"Hello World"(每个单词首字符,但仅限 ASCII + 默认分隔符) -
mb_convert_case("café monde", MB_CASE_TITLE, 'UTF-8')→"Café Monde"(真正支持多字节、重音、locale 无关)
真正需要标题格式化且数据来源不可控(如用户输入含中文、法语、德语)时,mb_convert_case 是唯一稳妥选择;否则 ucwords 足够轻量,但务必确认输入字符集和分隔符是否在它的能力范围内。
最常被忽略的一点:你写的 ucwords($input) 看似简单,一旦输入来自表单或数据库,就可能悄悄漏掉非 ASCII 字符的首字母大写——这不是函数失效,是你没意识到它的设计边界。



















