1 | <?php |
||
2 | |||
0 ignored issues
–
show
Coding Style
introduced
by
![]() |
|||
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 |