data = $this->getData(); } /** * 通过子集获取,全部父级 * @param int $id * @param string $file 全部父级字段 * @param string $Division 分割线 */ public function getParentS($id = 0, $file = '*', $Division = '') { $tAr = []; $rAr = []; while (true) { $data = $this->getParent($id); if (empty($data)) { break; } if (!empty($data)) { $tAr[] = $data; $id = $data['ParentId']; } } $tAr = array_reverse($tAr); foreach ($tAr as $v) { $rAr[] = ($file == '*' ? $v : $v[$file]); } if ($file != '*' && $Division != '') return join($Division, $rAr); else return $rAr; } /** * 获取子集所以Id * @param $id */ public function getChildIds($id) { $rAr = $this->getChilds($id); return array_column($rAr, 'ID'); } /** * 获取子集数据 * @param int $id */ public function getChild($id = 0) { $rAr = []; foreach ($this->data as $v) { if ($v['ParentId'] == $id) $rAr[] = $v; } return $rAr; } /** * 数据 * @param int $id * @return array */ public function getChilds($id = 0) { $data = $this->getChild($id); foreach ($data as $v) { $d = $this->getChilds($v['ID']); $data = array_merge($data, $d); } return $data; } /** * 上一层数 * @param int $parentId * @param string $file 字段 */ public function getParent($parentId = 0, $file = '*') { foreach ($this->data as $v) { if ($v['ID'] == $parentId) return ($file == '*' ? $v : $v[$file]); } return null; } /** * 获取层级数据 * @param int $lIndex */ public function getLevel($lIndex = 0) { $rAr = []; foreach ($this->data as $v) { if ($v['LevelType'] == $lIndex) $rAr[] = $v; } return $rAr; } /** * 模糊搜索ID * @param $name * @param string $file * @param int $parentId 上一层ID * @return mixed|null */ public function getLike($name, $file = '*', $parentId = -1) { if (empty($name)) return null; if ($parentId == -1) $data = $this->data; else $data = $this->getChilds($parentId); foreach ($data as $v) { if (strpos($v['Name'], $name) !== false) { return ($file == '*' ? $v : $v[$file]); } } return null; } /** * 获取地址到ID * @param $region */ public function getLikeS($name) { if (empty($name)) return 0; $nameAr = explode('-', $name); $province = 0; $city = 0; $area = 0; if (!empty($nameAr)) { $province = $this->getLike($nameAr[0], 'ID'); } if (count($nameAr) > 1) { $city = $this->getLike($nameAr[1], 'ID', $province); } if (count($nameAr) > 2) { $area = $this->getLike($nameAr[1], 'ID', $province); } if (!empty($area)) return $area; if (!empty($city)) return $city; if (!empty($province)) return $province; return 0; } /** * 查询地址信息 * @param type $id * @param type $file * @return type */ public function getField($id, $file = '*') { foreach ($this->data as $v) { if ($v['ID'] == $id) { return ($file == '*' ? $v : $v[$file]); } } return null; } public function getRegion($str) { $province = []; $city = []; $area = []; //省份获取 foreach ($this->data as $v) { $item = $v; $strLen = strpos($str, $item['ProvinceShortName']); if ($item['LevelType'] == 1 && $strLen !== false && (empty($province) || $province['len'] > $strLen) ) { $v['len'] = $strLen; $v['len2'] = strlen($item['ProvinceShortName']); $province = $v; } } //城市列表 if (!empty($province)) { $data = $this->getChild($province['ID']); if (count($data) == 1) { $city = $data[0]; $city['len'] = 0; } else { //匹配城市 | 地址前面优先匹配 $pLen = -1; foreach ($data as $v) { $str2 = substr($str . '-', $province['len'] + $province['len2'], -1); $strLen = strpos($str2, empty($v['CityShortName']) ? '' : $v['CityShortName']); if ($strLen !== false && $pLen == -1) { $pLen = $strLen; } if ($strLen !== false && $strLen <= $pLen && $v['LevelType'] == 2) { $v['len'] = $strLen + $province['len']; $city = $v; $pLen = $strLen; } } //可能城市和省会一样检测 if (empty($city)) { foreach ($data as $v) { $strLen = strpos($str, empty($v['CityShortName']) ? '' : $v['CityShortName']); if ($strLen !== false && $v['LevelType'] == 2) { $v['len'] = $strLen; $city = $v; break; } } } } } //地区数据 if (!empty($city)) { $data = $this->getChild($city['ID']); foreach ($data as $v) { $item = $v; $strLen = strpos($str, empty($item['DistrictShortName']) ? '' : $item['DistrictShortName']); if ($strLen !== false) { $v['len'] = $strLen; $area = $v; } } } //地区 foreach ($this->data as $v) { $item = $v; $strLen = strpos($str, $item['ProvinceShortName']); if ($item['LevelType'] == 3 && $strLen !== false && empty($city) && (empty($area) || $area['len'] < $strLen) ) { $v['len'] = $strLen; $area = $v; } } //////////// 详情地址 //////////// //省份 if (!empty($province)) { $len = strpos($str, $province['Name']); $name = $province['ProvinceShortName']; if ($len !== false && $len == $province['len']) { $name = $province['Name']; } $str = $this->strReplaceLimit($name, '', $str, 1); } //城市列表 if (!empty($city)) { $len = strpos($str, $city['Name']); $name = $city['CityShortName']; if ($len !== false) { $name = $city['Name']; } $str = $this->strReplaceLimit($name, '', $str, 1); } //城市列表 if (!empty($area)) { $len = strpos($str, $area['Name']); $name = $area['DistrictShortName']; if ($len !== false) { $name = $area['Name']; } $str = $this->strReplaceLimit($name, '', $str, 1); } //var_dump(['address'=>trim($str),'province'=> empty($province) ? '' : $province['Name'],'city'=> empty($city) ? '' : $city['Name'],'area'=>empty($area) ? '' : $area['Name']]); return ['address' => trim($str), 'province' => empty($province) ? '' : $province['Name'], 'city' => empty($city) ? '' : $city['Name'], 'area' => empty($area) ? '' : $area['Name']]; } /** * 获取基础数据【缓存数据】 */ private function getData() { $data = cache('region'); if (empty($data)) { $data = Db::name("region")->field("ID,ParentId,LevelType,Name,Pinyin,ProvinceShortName,DistrictShortName,CityShortName")->select()->toArray(); cache('region', $data); } return $data; } /** * @param $method * @param $args * @return mixed */ public static function __callStatic($method, $args) { $model = new static(); return call_user_func_array([$model, $method], $args); } /** * $search:要替换的字符串或者数组 * $replace:要替换的值 * $subject:要替换的文本 * $limit:替换的此数字 * @return string|string[]|null */ function strReplaceLimit($search, $replace, $subject, $limit = -1) { if (is_array($search)) { foreach ($search as $k => $v) { $search[$k] = '`' . preg_quote($search[$k], '`') . '`'; } } else { $search = '`' . preg_quote($search, '`') . '`'; } return preg_replace($search, $replace, $subject, $limit); } }