PHP游客聊天登录昵称不支持纯阿拉伯语输入问题排查
错误原因
错误由两处代码逻辑问题共同导致:
- 严格过滤规则的白名单限制
sanitize_username函数在$strict = true模式下会执行正则preg_replace('|[^a-z0-9 _.\-]|i', '', $username),该规则仅保留英文字母、数字、空格、下划线、点、横杠,所有不在白名单内的字符都会被直接删除,阿拉伯语字符不属于白名单范围,会被完全清空。 - 严格模式开关逻辑写反
核心业务代码中$strict_mode的判断完全颠倒:默认开启严格过滤,仅当「非拉丁用户名功能未启用」时才关闭严格模式。这就导致后台开启非拉丁用户名支持时,反而会触发最严格的英文字符白名单过滤,把所有非英文内容全部删除。
你观察到的三个现象完全匹配上述逻辑:
- 输入英文昵称:所有字符都在白名单内,无删除,正常提交
- 输入纯阿拉伯语昵称:所有字符被过滤为空,触发
empty(trim($data['username']))校验失败,返回Invalid Input or Field Empty错误 - 阿拉伯语混合数字输入:阿拉伯语部分被删除,但数字属于白名单内容被保留,得到非空的纯数字字符串通过校验;如果该纯数字用户名已存在,系统会自动拼接
_随机字符串后缀,最终生成数字_随机字符串格式的用户名。
修复方案
1. 修正严格模式判断逻辑
将写反的开关逻辑替换为正确逻辑:默认关闭严格模式,仅当系统不允许非拉丁用户名时,才开启英文字符白名单过滤。
替换核心业务代码中对应片段:
// 原错误逻辑 // $strict_mode = true; // if (Registry::load('settings')->non_latin_usernames !== 'enable') { // $strict_mode = false; // } // 修正后逻辑 $strict_mode = false; if (Registry::load('settings')->non_latin_usernames !== 'enable') { $strict_mode = true; }
2. 修复多字节字符匹配问题
给sanitize_username函数内所有正则规则加上u修饰符,让PHP按UTF-8编码处理阿拉伯语这类多字节字符,避免字符误判、乱码、误删问题。修改后的完整函数如下:
function sanitize_username($username, $strict = false) { $username = strip_all_tags($username); $username = remove_accents($username); $username = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|u', '', $username); $username = preg_replace('/&.+?;/u', '', $username); if ($strict) { $username = preg_replace('|[^a-z0-9 _.\-]|iu', '', $username); } $username = str_replace(array('\'', '"', ',', '@', ';', '(', ')', '[', ']', '<', '>', '{', '}', '?', '&'), '', $username); $username = trim($username); $username = preg_replace('|\s+|u', ' ', $username); $username = preg_replace('/\s+/u', '-', $username); return $username; }
修改完成后,后台开启「非拉丁用户名」功能时,纯阿拉伯语昵称不会被过滤,可正常提交使用;关闭该功能时仍仅允许英文字母、数字组合的用户名,符合原有设计预期。
内容的提问来源于stack exchange,提问作者Mohammed alkenani
相关产品推荐
相关产品推荐

