PHP身份证格式,合法性,是否未成年验证

//测试
    public function test(){
        $IDCard = $_GET['id'];

        $result['error'] = 0;//0:未知错误,1:身份证格式错误,2:无错误
        $result['isAdult'] = '';//0标示成年,1标示未成年
        $result['birthday'] = '';//生日,格式如:2012-11-15
        //省份数据
        $city = array(
            11  => "北京",
            12  => "天津",
            13  => "河北",
            14  => "山西",
            15  => "内蒙古",
            21  => "辽宁",
            22  => "吉林",
            23  => "黑龙江",
            31  => "上海",
            32  => "江苏",
            33  => "浙江",
            34  => "安徽",
            35  => "福建",
            36  => "江西",
            37  => "山东",
            41  => "河南",
            42  => "湖北",
            43  => "湖南",
            44  => "广东",
            45  => "广西",
            46  => "海南",
            50  => "重庆",
            51  => "四川",
            52  => "贵州",
            53  => "云南",
            54  => "西藏 ",
            61  => "陕西",
            62  => "甘肃",
            63  => "青海",
            64  => "宁夏",
            65  => "新疆",
            71  => "台湾",
            81  => "香港",
            82  => "澳门",
            91  => "国外",
        );
        // var_dump(!preg_match("/^[1-9]([0-9a-zA-Z]{17}|[0-9a-zA-Z]{14})$/i", $IDCard));die;
        // var_dump((bool)preg_match("/^[1-9]\d{5}(19|20|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/", $IDCard) === false);die;
        
        //验证格式是否正确
        if((bool)preg_match("/^[1-9]\d{5}(19|20|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/", $IDCard) === false){
            $result['error'] = 1;
        }else if( isset($city[intval(substr($IDCard, 0, 2))]) === false ){  
            //验证省份是否正确
            $result['error'] = 1;
        }else{
            //判断当前身份证是几位数
            if(strlen($IDCard) == 18){
            //合法性验证
                //转化为大写,如出现x
                $idcard = strtoupper($IDCard);
                //加权因子
                $wi = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
                $ai = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
                //按顺序循环处理前17位
                $sigma = 0;
                //提取前17位的其中一位,并将变量类型转为实数
                for ($i = 0; $i < 17; $i++) {
                    $b = (int)$idcard{$i};
                    //提取相应的加权因子
                    $w = $wi[$i];
                    //把从身份证号码中提取的一位数字和加权因子相乘,并累加
                    $sigma += $b * $w;
                }
                //计算序号
                $sidcard = $sigma % 11;
                //按照序号从校验码串中提取相应的字符。
                $check_idcard = $ai[$sidcard];
                if($idcard{17} != $check_idcard){  
                    $result['error'] = 0;
                }else{
                    //年份
                    $tyear = intval(substr( $IDCard,6,4));
                    //月份
                    $tmonth = intval(substr( $IDCard,10,2));
                    //日
                    $tday = intval(substr( $IDCard,12,2));
                    //判断年月日 再判断是否未成年
                    if( $tyear > date("Y") || $tyear < (date("Y") - 100)){
                        $result['error'] = 0;
                    }elseif($tmonth < 0 || $tmonth > 12){
                        $result['error'] = 0;
                    }elseif($tday < 0 || $tday > 31){
                        $result['error'] = 0;
                    }else{
                        //根据年月日判断是否成年
                        $tdate = $tyear."-".$tmonth."-".$tday." 00:00:00";
                        //获得出生年月日的时间戳
                        $date = strtotime(substr($IDCard,6,8));
                        //获得今日的时间戳 
                        $today = strtotime('today');
                        //得到两个日期相差的大体年数 
                        $diff = floor(($today-$date)/86400/365);
                        //strtotime加上这个年数后得到那日的时间戳后与今日的时间戳相比 
                        $agee = strtotime(substr($IDCard,6,8).' +'.$diff.'years')>$today?($diff+1):$diff;
                        //当前时间减去年月日,获取查询的实际年龄的时间戳,如果大于18岁的时间戳则成年,小于则未成年
                        if((time() - mktime(0, 0, 0, $tmonth, $tday, $tyear)) > 18 * 365 * 24 * 60 * 60){
                            $flag = 0;
                            $result['error'] = 2;
                            $age = $agee;
                        }else{
                            $flag = 1;
                            $result['error'] = 2;
                            $age = $agee;
                        }
                    }
                }
            }elseif( strlen($IDCard) == 15){
                $tyear = intval("19".substr( $IDCard, 6, 2));
                $tmonth = intval(substr( $IDCard, 8, 2));
                $tday = intval(substr( $IDCard, 10, 2));
                if( $tyear > date("Y") || $tyear < ( date("Y") - 100) ){
                    $result['error'] = 0;
                }elseif( $tmonth < 0 || $tmonth > 12){
                    $result['error'] = 0;
                }elseif( $tday < 0 || $tday > 31){
                    $result['error'] = 0;
                }else{
                    $tdate = $tyear."-".$tmonth."-".$tday." 00:00:00";
                    if((time() - mktime( 0, 0, 0, $tmonth, $tday, $tyear)) > 18 * 365 * 24 * 60 * 60){
                        $flag = 0;
                        $result['error'] = 2;
                    }else{
                        $flag = 1;
                        $result['error'] = 2;
                    }
                }
            }

        }

        if ($result['error'] == 2) {
            $result['isAdult'] = $flag;//0标示成年,1标示未成年
            $result['birthday'] = $tdate;//生日日期
            $result['age'] = $age;
        }else if ($result['error'] == 1) {
            $result['error'] = '身份证格式错误';//0:未知错误,1:身份证格式错误,2:无错误
            unset( $result['isAdult']);
            unset( $result['birthday']);
        }else if ($result['error'] == 0) {
            $result['error'] = '请填写正确的身份证';//0:未知错误,1:身份证格式错误,2:无错误
            unset( $result['isAdult']);
            unset( $result['birthday']);
        }
        var_dump($result);die;
        // return $result;  
    }

 

你可能感兴趣的:(干货,技术,分享,身份证正则,身份证合法性,是否未成年)