2020-09-22 更新

使用隐藏手机号、电话函数的过程中发现,有些号码并没有实现脱敏处理,比如 173***。检查代码发现,/(1[358]{1}[0-9])[0-9]{4}([0-9]{4})/i 只能匹配 13、15、18 开头的手机号,匹配手机号的正则表达式不够精准。

网上找到一个 中国大陆手机号正则表达式大全 - github,其中匹配所有支持短信功能的号码(手机卡 + 上网卡)的正则为:

^(?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[0-35-9]\d{2}|4(?:0\d|1[0-2]|9\d))|9[0-35-9]\d{2}|6[2567]\d{2}|4[579]\d{2})\d{6}$

测试了几个新号码,匹配正常。以下为升级版的手机号、固定电话脱敏处理函数:

/**
 * 隐藏手机号
 * @param $phone
 * @return string|string[]|null
 */
function hidtel($phone){
    $IsWhat = preg_match('/(0[0-9]{2,3}[\-]?[2-9][0-9]{6,7}[\-]?[0-9]?)/i', $phone); //固定电话
    if($IsWhat == 1){
        return preg_replace('/(0[0-9]{2,3}[\-]?[2-9])[0-9]{3,4}([0-9]{3}[\-]?[0-9]?)/i','$1****$2', $phone);
    } else if (preg_match('^(?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[0-35-9]\d{2}|4(?:0\d|1[0-2]|9\d))|9[0-35-9]\d{2}|6[2567]\d{2}|4[579]\d{2})\d{6}$', $phone)) {
        return preg_replace('/([0-9]{3})[0-9]{4}([0-9]{4})/i','$1****$2', $phone);
    } else {
        return preg_replace('/([0-9]{3})[0-9]{4}([0-9]{4})/i','$1****$2', $phone);
    }
}

外卖订单或者物流快递单为保护个人隐私,需要隐藏手机号中间四位,真实姓名需要隐藏名的部分。

话不多说直接上代码:

隐藏真实手机号、电话

    /**
     * 隐藏手机号
     * @param $phone
     * @return string|string[]|null
     */
    function hidtel($phone){
        $IsWhat = preg_match('/(0[0-9]{2,3}[\-]?[2-9][0-9]{6,7}[\-]?[0-9]?)/i',$phone); //固定电话
        if($IsWhat == 1){
            return preg_replace('/(0[0-9]{2,3}[\-]?[2-9])[0-9]{3,4}([0-9]{3}[\-]?[0-9]?)/i','$1****$2',$phone);
        }else{
            return preg_replace('/(1[358]{1}[0-9])[0-9]{4}([0-9]{4})/i','$1****$2',$phone);
        }
    }

隐藏真实姓名

    /**
     * 隐藏姓名
     * @param $name
     * @return string
     */
    function hidname($name) {
        $cnt = mb_strlen($name) - 1;
        $res = mb_substr($name, 0, 1);
        for ($i=0; $i<$cnt; $i++) {
            $res .= '*';
        }
        return $res;
    }

很明显,使用正则匹配替换的是别人写的,下面是自己拼凑的 OωO 。