老用户在国外用 +86 138xxxx 登录,提示账号不存在,库里存的其实是 138xxxx 这十一位。从网页注册的都正常,从 App 注册的全中招。乍看像缓存或者权限的锅,追下去往往不是。
$raw = preg_replace('/\D/', '', $phone);
$local = preg_replace('/^(0086|86)(?=1\d{10}$)/', '', $raw);
// 库里统一存 11 位,发送时再补 +86
追下去是这么回事:手机号入库前没统一格式,App 端带了国家码,网页端只存了本地号。查询时按原样等值匹配,字符串不同就查不到,和号码本身对不对没关系。
「手机号区号归一」这类改动最怕改一半,回滚脚本先准备好,再动生产。测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。
线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。
具体做法是,入库和查询都先过一遍归一函数,去掉空格横线,把 +86 和 0086 统一剥掉;存量数据按长度分组,把带区号的挑出来批量修正;短信发送前再拼回带区号的格式,存储和发送分开处理;用 +86、0086、纯 11 位三种写法各登录一次。
验收就看一点,三种写法的手机号都能登进同一个账号,短信也照常收到。
