jxlwqq /
id-validator
| 1 | <?php |
||
| 2 | |||
|
0 ignored issues
–
show
Coding Style
introduced
by
Loading history...
|
|||
| 3 | namespace Jxlwqq\IdValidator; |
||
| 4 | |||
| 5 | /** |
||
| 6 | * Trait Helper. |
||
| 7 | */ |
||
|
0 ignored issues
–
show
|
|||
| 8 | trait Helper |
||
| 9 | { |
||
| 10 | /** |
||
| 11 | * 获取地址码信息. |
||
| 12 | * |
||
| 13 | * @param string $addressCode 地址码 |
||
| 14 | * @param string $birthdayCode 出生日期码 |
||
| 15 | * @param bool $strictMode 是否启动严格模式检查 |
||
| 16 | * |
||
| 17 | * @return bool|mixed|string |
||
| 18 | */ |
||
| 19 | private function _getAddressInfo($addressCode, $birthdayCode, $strictMode = false) |
||
| 20 | { |
||
| 21 | $addressInfo = [ |
||
| 22 | 'province' => '', |
||
| 23 | 'city' => '', |
||
| 24 | 'district' => '', |
||
| 25 | ]; |
||
| 26 | |||
| 27 | // 省级信息 |
||
| 28 | $provinceAddressCode = substr($addressCode, 0, 2).'0000'; |
||
| 29 | $addressInfo['province'] = $this->_getAddress($provinceAddressCode, $birthdayCode, $strictMode); |
||
| 30 | |||
| 31 | $firstCharacter = $addressCode[0]; // 用于判断是否是港澳台居民居住证(8字开头) |
||
| 32 | |||
| 33 | // 港澳台居民居住证无市级、县级信息 |
||
| 34 | if ($firstCharacter == '8') { |
||
| 35 | return $addressInfo; |
||
| 36 | } |
||
| 37 | |||
| 38 | // 市级信息 |
||
| 39 | $cityAddressCode = substr($addressCode, 0, 4).'00'; |
||
| 40 | $addressInfo['city'] = $this->_getAddress($cityAddressCode, $birthdayCode, $strictMode); |
||
| 41 | |||
| 42 | // 县级信息 |
||
| 43 | $addressInfo['district'] = $this->_getAddress($addressCode, $birthdayCode, $strictMode); |
||
| 44 | |||
| 45 | // 这里不判断市级信息的原因: |
||
| 46 | // 1)直辖市,无市级信息 |
||
| 47 | // 2)省直辖县或县级市,无市级信息 |
||
| 48 | return (empty($addressInfo['district']) or empty($addressInfo['province'])) ? false : $addressInfo; |
||
| 49 | } |
||
| 50 | |||
| 51 | /** |
||
| 52 | * 获取省市区地址码. |
||
| 53 | * |
||
| 54 | * @param string $addressCode 地址码 |
||
| 55 | * @param string $birthdayCode 出生日期码 |
||
| 56 | * @param bool $strictMode 是否启动严格模式检查 |
||
| 57 | * |
||
| 58 | * @return string |
||
| 59 | */ |
||
| 60 | private function _getAddress($addressCode, $birthdayCode, $strictMode = false) |
||
| 61 | { |
||
| 62 | $address = ''; |
||
| 63 | if (isset($this->_addressCodeTimeline[$addressCode])) { |
||
| 64 | $timeline = $this->_addressCodeTimeline[$addressCode]; |
||
| 65 | $year = substr($birthdayCode, 0, 4); |
||
| 66 | // 严格模式下,会检查【地址码正式启用的年份】与【身份证上的出生年份】 |
||
| 67 | foreach ($timeline as $val) { |
||
| 68 | $start_year = $val['start_year'] != '' ? $val['start_year'] : '0001'; |
||
| 69 | $end_year = $val['end_year'] != '' ? $val['end_year'] : '9999'; |
||
| 70 | if ($year >= $start_year and $year <= $end_year) { |
||
| 71 | $address = $val['address']; |
||
| 72 | } |
||
| 73 | } |
||
| 74 | |||
| 75 | // 非严格模式下,则不会检查【地址码正式启用的年份】与【身份证上的出生年份】的关系 |
||
| 76 | if (empty($address) and !$strictMode) { |
||
| 77 | // 由于较晚申请户口或身份证等原因,导致会出现地址码正式启用于2000年,但实际1999年出生的新生儿,由于晚了一年报户口,导致身份证上的出生年份早于地址码正式启用的年份 |
||
| 78 | // 由于某些地区的地址码已经废弃,但是实际上在之后的几年依然在使用 |
||
| 79 | // 这里就不做时间判断了 |
||
| 80 | return array_pop($timeline)['address']; |
||
| 81 | } |
||
| 82 | |||
| 83 | return $address; |
||
| 84 | } |
||
| 85 | |||
| 86 | // 修复 \d\d\d\d01、\d\d\d\d02、\d\d\d\d11 和 \d\d\d\d20 的历史遗留问题 |
||
| 87 | // 以上四种地址码,现实身份证真实存在,但民政部历年公布的官方地址码中可能没有查询到 |
||
| 88 | // 如:440401 450111 等 |
||
| 89 | // 所以这里需要特殊处理 |
||
| 90 | // 1980年、1982年版本中,未有制定省辖市市辖区的代码,所有带县的省辖市给予“××××20”的“市区”代码。 |
||
| 91 | // 1984年版本开始对地级市(前称省辖市)市辖区制定代码,其中“××××01”表示市辖区的汇总码,同时撤销“××××20”的“市区”代码(追溯至1983年)。 |
||
| 92 | // 1984年版本的市辖区代码分为城区和郊区两类,城区由“××××02”开始排起,郊区由“××××11”开始排起,后来版本已不再采用此方式,已制定的代码继续沿用。 |
||
| 93 | $suffixes = substr($addressCode, 4, 2); |
||
| 94 | switch ($suffixes) { |
||
| 95 | case '20': |
||
|
0 ignored issues
–
show
|
|||
| 96 | $address = '市区'; |
||
| 97 | break; |
||
| 98 | case '01': |
||
|
0 ignored issues
–
show
|
|||
| 99 | $address = '市辖区'; |
||
| 100 | break; |
||
| 101 | case '02': |
||
|
0 ignored issues
–
show
|
|||
| 102 | $address = '城区'; |
||
| 103 | break; |
||
| 104 | case '11': |
||
|
0 ignored issues
–
show
|
|||
| 105 | $address = '郊区'; |
||
| 106 | break; |
||
| 107 | } |
||
| 108 | |||
| 109 | return $address; |
||
| 110 | } |
||
| 111 | |||
| 112 | /** |
||
| 113 | * 获取星座信息. |
||
| 114 | * |
||
| 115 | * @param string $birthdayCode 出生日期码 |
||
| 116 | * |
||
| 117 | * @return string |
||
| 118 | */ |
||
| 119 | private function _getConstellation($birthdayCode) |
||
| 120 | { |
||
| 121 | $constellationList = include __DIR__.'/../data/constellation.php'; |
||
| 122 | $month = (int) substr($birthdayCode, 4, 2); |
||
| 123 | $day = (int) substr($birthdayCode, 6, 2); |
||
| 124 | |||
| 125 | $start_date = $constellationList[$month]['start_date']; |
||
| 126 | $start_day = (int) explode('-', $start_date)[1]; |
||
| 127 | |||
| 128 | if ($day < $start_day) { |
||
| 129 | $tmp_month = $month == 1 ? 12 : $month - 1; |
||
| 130 | |||
| 131 | return $constellationList[$tmp_month]['name']; |
||
| 132 | } |
||
| 133 | |||
| 134 | return $constellationList[$month]['name']; |
||
| 135 | } |
||
| 136 | |||
| 137 | /** |
||
| 138 | * 获取生肖信息. |
||
| 139 | * |
||
| 140 | * @param string $birthdayCode 出生日期码 |
||
| 141 | * |
||
| 142 | * @return mixed |
||
| 143 | */ |
||
| 144 | private function _getChineseZodiac($birthdayCode) |
||
| 145 | { |
||
| 146 | $chineseZodiacList = include __DIR__.'/../data/chineseZodiac.php'; |
||
| 147 | $start = 1900; // 子鼠 |
||
| 148 | $end = substr($birthdayCode, 0, 4); |
||
| 149 | $key = ($end - $start) % 12; |
||
| 150 | |||
| 151 | return $chineseZodiacList[$key]; |
||
| 152 | } |
||
| 153 | } |
||
| 154 |