您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > php

PHP实现地址自动识别实例

时间:2019-06-17 14:57:04  来源:  作者:

址自动识别现在普遍,特别是用在快递填写地址,姓名,手机号码的时候,会把这些按照一定的规范填写后,点击自动识别后,会自动填写到各自的input。最近也简单的实现了这个功能,给后台添加用户的时候,自动识别地址。以下是效果图

 

实现地址自动识别实例(PHP)

 

具体问题具体分析!代码实现基于laravel完成。一个laravel完整的功能得具备这些:路由route,Model, View, Controller, 我这里用的有依赖注入服务容器等功能,当然,用到地址,你首先要有地址库。。。

下面来看看是如何实现的,这里我只贴出核心代码

UsersController控制器

在这里新建构造函数,实现容器的依赖注入UsersRepository

/** @var UserRepository */
private $userRepository;
public function __construct(UsersRepository $userRepo)
{
 $this->userRepository = $userRepo;
}

 

接下来就新建地址识别的方法, $discernDel 接收的数据是从前端传过来的,后面再贴前端代码。 业务代码处理交给容器UsersRepository里的方法getDiscern处理

/**
 * Function:地址识别
 * Author:cyw0413
 * @param Request $request
 * @return IlluminateContractsRoutingResponseFactory|IlluminateHttpResponse|
 * LaravelLumenHttpResponseFactory|SymfonyComponentHttpFoundationResponse
 */
public function getDiscern(Request $request)
{
 $discernDel = $request->input('discernDel');
 try{
 DB::beginTransaction();
 $address = $this->userRepository->getDiscern($discernDel);
 DB::commit();

 }catch (Exception $e){
 DB::rollBack();
 $msg = "信息提示:".$e->getMessage().",行:".$e->getLine();
 return response(['code' => 0, 'msg'=>$msg]);
 }

 return response(['code'=>1,'msg'=>$address]); //地址识别完成

}

 

来看看userRepository容器处理地址识别的各种业务代码

/**
 * Function:识别地址
 * Author:cyw0413
 */
public function getDiscern($discernDel)
{
 if (empty($discernDel)) {
 throw new Exception("请传入要识别的地址");
 }

 $discernDel_left = explode ('[', $discernDel);
 if (!isset($discernDel_left[1])) {
 throw new Exception("你填写的地址规则错误,手机号码应该用[]");
 }
 $discernDel_right = explode (']', $discernDel_left[1]);
 if (!isset($discernDel_right[1]) || empty($discernDel_right[1])) {
 throw new Exception("你填写的地址规则错误,手机号码应该用[]");
 }

 $name = $discernDel_left[0];
 if (empty($name)) {
 throw new Exception("你填写的姓名有误!");
 }
 $mobile = $discernDel_right[0];
 if (empty($mobile) || checkMobile($mobile) == 0) {
 throw new Exception("你填写的手机号码格式有误!");
 }
 $address = trim ($discernDel_right[1]);
 if (empty($address)) {
 throw new Exception("你填写的地址不能为空");
 }

 $var_address = $this->getAddressArrar($address);
 $var_address['name'] = $name;
 $var_address['mobile'] = $mobile;

 return $var_address;

}

上面的方法处理手机,名称,和地址处理,地址处理有些繁杂,因为有时候填写的地址有不一样的,比如广西省,有些就填写广西壮族自治区,所以getAddressArrar方法处理地址匹配信息,根据自己的业务做调整,如下

/**
 * Function:地址的处理
 * Author:cyw0413
 * @param $address
 * @return array
 * @throws Exception
 */
function getAddressArrar($address){
 // 获取所有地址递归列表
 $regions = $this->getRegions();
 // 初始化数据
 $province = $city = $district = [];
 // 先查找省份-第一级地区
 $province = $this->checkAddress($address, $regions);
 if($province){

 $province_arr = ['110000','300000','404100','310000']; //4个市辖区如果地址不存在二级(市辖区,县),则特殊处理
 if(!isset($province['region_code'])){
 throw new Exception("请正确填写省份(市辖区)");
 }
 // 查找城市-第二级地区
 $city = $this->checkAddress($address, $province['list']);
 //这里只处理4个市辖区,可能还有多种情况,待发现
 if(in_array($province['region_code'],$province_arr) && count($city['list']) == 0){
 $city = $this->checkAddress('市辖区', $province['list']);
 if($city){
 // 查找地区-第三级地区
 $district = $this->checkAddress($address, $city['list']);
 //如果没有找到,则查找另外一个二级地区
 if(!isset($district['region_code'])){
 $city = $this->checkAddress('县', $province['list']);
 // 查找地区-第三级地区
 $district = $this->checkAddress($address, $city['list']);
 }
 }
 }else{

 if($city){
 // 查找地区-第三级地区
 $district = $this->checkAddress($address, $city['list']);
 }
 }

 }else{
 //省份不填,报错误
 throw new Exception("省份没填写,请检查");
 }

 return $this->getAddressInfo($address, $province, $city, $district);
}

 

/**
 * 匹配正确的城市地址
 * @param $address
 * @param $city_list
 * @param int $force
 * @param int $str_len
 * @return array
 **/
function checkAddress($address, $city_list, $force=false, $str_len=2){
 $num = 0;
 $list = array();
 $result = array();
 // 遍历所有可能存在的城市
 foreach ($city_list as $city_key=>$city){
 $city_name = mb_substr($city['region_name'], 0, $str_len,'utf-8');
 // 判断是否存包含当前地址字符
 $city_arr = explode($city_name, $address);


 // 如果存在相关字眼,保存该地址的所有子地址
 if(count($city_arr) >= 2){
 // 必须名称长度同时达到当前比对长度
 if(strlen($city['region_name']) < $str_len){
 continue;
 }
 $num ++;
 if(isset($city['child'])){
 $list = $list + $city['child'];
 }

 $result[] = array(
 'region_code' => $city_key,
 'region_name' => $city['region_name'],
 'list' =>$list,
 );
 }
 }

 // 如果有多个存在,则加大字符匹配长度
 if($num > 1 || $force){
 $region_name1 = $result[0]['region_name'];
 $region_name2 = $result[1]['region_name'];

 if(strlen($region_name1) == strlen($region_name2) && strlen($region_name1) == $str_len){
 $region_id1 = $result[0]['region_code'];
 $region_id2 = $result[1]['region_code'];
 $index = $region_id1 > $region_id2 ? 1 : 0;
 $result = $result[$index];
 return $result;
 }
 return $this->checkAddress($address, $city_list, $force, $str_len+1);
 } else {
 $result[0]['list'] = $list;
 return $result[0];
 }
}

 

/**
 * 根据原地址返回详细信息
 * @param $address
 * @param $province
 * @param $city
 * @param $area
 * @return array
 **/
function getAddressInfo($address, $province, $city, $district){
 // 查找最后出现的地址 - 截取详细信息
 if(!isset($province['region_name'])){
 throw new Exception("请检查并正确填写省份(市辖区)");
 }
 if(!isset($city['region_name'])){
 throw new Exception("请检查并正确填写城市");
 }
 if(!isset($district['region_name'])){
 throw new Exception("请检查并正确填写区域(县/区/镇)");
 }
 $find_str = '';
 if($province['region_name']){
 $find_str = $province['region_name'];
 if($city['region_name']){
 $find_str = $city['region_name'];
 if(isset($district['region_name']) && $district['region_name']){
 $find_str = $district['region_name'];
 }
 }
 }
 // 截取详细的信息
 $find_str_len = mb_strlen($find_str,'utf-8');
 for($i=0; $i<$find_str_len-1; $i++){
 $substr = mb_substr($find_str,0,$find_str_len - $i, 'utf-8');
 $end_index = mb_strpos($address, $substr);
 if ($end_index){
 $address = mb_substr($address, $end_index + mb_strlen($substr) , mb_strlen($address) - $end_index);
 }
 }
 !empty($find_str) && $find_str = '|S*' . $find_str;
 $area['info'] = preg_replace("/s*|,|,|:|:{$find_str}/i", '', $address);
 if(empty($area['info'])){
 throw new Exception("详细地址不存在,请检查");
 }

 return $address = [
 'province' => $province['region_code'],
 'city' => $city['region_code'],
 'district' => $district['region_code'],
 'info' => $area['info']
 ];
}

前端html部分代码

基本上能看得懂的。jquery用到 getDiscern();方法,手机号码,姓名,地址等input这里就不一一列出了。大家根据下面的jquery都能想象到

<div class="form-group">
 {!! Form::label('discern', '自动识别地址:',['class' => 'control-label col-sm-2']) !!}
 <div class="col-sm-5">
 {!! Form::textarea('discern', '', ['class' => 'form-textarea form-control form-discern','rows' => 3]) !!}
 </div>
 <div class="col-sm-3" style="height: 75px;">
 <button type="button" class="btn btn-info btn-sm discern" onclick="getDiscern();" >提交识别</button>
 <small class="ruleGet" style="color: #676a74;">*查看模板</small>
 </div>

</div>

 

jquery代码部分

ajax post后交给url:getDiscern 处理,这个就是上面controller的方法,success返回的数据后再追加到每个input里,最后再清除掉自动识别地址框的数据

/**
 * 地址识别
 * @returns {boolean}
 */
function getDiscern(){
 var discernDel = $(".form-discern").val();
 if(!discernDel){
 alert("请输入要识别的地址");
 return false;
 }

 $.ajax({
 type: 'POST',
 url: "{!! route('admin.user.getDiscern') !!}",
 data: {
 '_token': csrf_token(),
 'discernDel': discernDel
 },
 dataType: 'json',
 timeout: 50000,
 success: function (res) {
 if (res.code == 1) {
 $("input[name='addr[linkman]']").val(res.msg.name);
 $("input[name='user_name']").val(res.msg.mobile);
 $("input[name='addr[address]']").val(res.msg.info);

 //触发change事件
 $('#province').val(res.msg.province).trigger('change');
 $('#city').val(res.msg.city).trigger('change');
 $('#area').val(res.msg.district).trigger('change');

 //识别后清除
 $(".form-discern").val("");

 } else {
 alert(res.msg);
 }
 }
 })

}

 

整个过程简单,又清晰明了,以上就是小编的代码,分享给大家,觉得哪个地方不对劲的,欢迎留言吐槽!
 



Tags:PHP   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
网络地址来源:获取公网IP地址 https://ipip.yy.com/get_ip_info.phphttp://pv.sohu.com/cityjson?ie=utf-8http://www.ip168.com/json.do?view=myipaddress...【详细内容】
2021-12-15  Tags: PHP  点击:(15)  评论:(0)  加入收藏
一、编程语言1.根据熟悉的语言,谈谈两种语言的区别?主要浅谈下C/C++和PHP语言的区别:1)PHP弱类型语言,一种脚本语言,对数据的类型不要求过多,较多的应用于Web应用开发,现在好多互...【详细内容】
2021-12-15  Tags: PHP  点击:(17)  评论:(0)  加入收藏
序言:前段时间织梦因为版权的问题在网上闹得沸沸扬扬,也提醒了众多开发者选择cms上应该谨慎使用,今天给大家展示一款自己搭建的内容管理系统,不用担心版权的问题,而且非常容易维...【详细内容】
2021-11-30  Tags: PHP  点击:(34)  评论:(0)  加入收藏
序言:习惯了用集成软件来安装php的运行环境,单独配置php、apache成为了部分程序员不愿意面对的问题,下面和我一块来复习一下,赶紧点赞收藏吧。 php官方下载地址https://windows....【详细内容】
2021-11-23  Tags: PHP  点击:(24)  评论:(0)  加入收藏
准备安装包(PHP: Hypertext Preprocessor)下载安装包以及组件wget https://www.php.net/distributions/php-8.0.0.tar.bz2wget https://github.com/phpredis/phpredis/archive...【详细内容】
2021-11-09  Tags: PHP  点击:(40)  评论:(0)  加入收藏
golang context 很好用,就使用php实现了github地址 : https://github.com/qq1060656096/php-go-context context使用闭坑指南1. 将一个Context参数作为第一个参数传递给传入和...【详细内容】
2021-11-05  Tags: PHP  点击:(41)  评论:(0)  加入收藏
TechEmpower BenchmarkTechEmpower 的测试比较科学,包含 SQL 查询、JSON 序列化等各种测试,同时标注了哪些是使用了 ORM,哪些是 RAW 查询。 TechEmpower Benchmark Web Framew...【详细内容】
2021-10-12  Tags: PHP  点击:(71)  评论:(0)  加入收藏
一、背景介绍Pikachu是一个带有各种漏洞的Web应用系统,这个系统是使用PHP搭建的,需要PHP环境和Mysql数据库支持。我们可以利用phpstudy在本地搭建这个渗透测试平台,如果你是一...【详细内容】
2021-10-09  Tags: PHP  点击:(53)  评论:(0)  加入收藏
一段数组为例:$list = array:4 [ 0 => array:7 [ "id" => 56 "mer_id" => 7 "order_id" => "wx163265961408769974" "is_postage" => 0 "store_name" => "奇...【详细内容】
2021-09-29  Tags: PHP  点击:(65)  评论:(0)  加入收藏
利用JS的CryptoJS 3.x和PHP的openssl_encrypt,openssl_decrypt实现AES对称加密解密,由于需要两种语言对同一字符串的操作,而CryptoJS 的默认加密方式为“aes-256-cbc”,PHP端也...【详细内容】
2021-09-16  Tags: PHP  点击:(79)  评论:(0)  加入收藏
▌简易百科推荐
序言:前段时间织梦因为版权的问题在网上闹得沸沸扬扬,也提醒了众多开发者选择cms上应该谨慎使用,今天给大家展示一款自己搭建的内容管理系统,不用担心版权的问题,而且非常容易维...【详细内容】
2021-11-30  小程序软件开发    Tags:管理系统   点击:(34)  评论:(0)  加入收藏
准备安装包(PHP: Hypertext Preprocessor)下载安装包以及组件wget https://www.php.net/distributions/php-8.0.0.tar.bz2wget https://github.com/phpredis/phpredis/archive...【详细内容】
2021-11-09  mimic96    Tags:PHP   点击:(40)  评论:(0)  加入收藏
golang context 很好用,就使用php实现了github地址 : https://github.com/qq1060656096/php-go-context context使用闭坑指南1. 将一个Context参数作为第一个参数传递给传入和...【详细内容】
2021-11-05  1060656096    Tags:PHP   点击:(41)  评论:(0)  加入收藏
一段数组为例:$list = array:4 [ 0 => array:7 [ "id" => 56 "mer_id" => 7 "order_id" => "wx163265961408769974" "is_postage" => 0 "store_name" => "奇...【详细内容】
2021-09-29  七七小影视    Tags:PHP   点击:(65)  评论:(0)  加入收藏
利用JS的CryptoJS 3.x和PHP的openssl_encrypt,openssl_decrypt实现AES对称加密解密,由于需要两种语言对同一字符串的操作,而CryptoJS 的默认加密方式为“aes-256-cbc”,PHP端也...【详细内容】
2021-09-16  李老师tome    Tags:对称加密   点击:(79)  评论:(0)  加入收藏
1、checkdate()验证格利高里日期即:日期是否存在。checkdate(month,day,year);month必需。一个从 1 到 12 的数字,规定月。day必需。一个从 1 到 31 的数字,规定日。year必需。...【详细内容】
2021-08-31  七七小影视    Tags:时间函数   点击:(80)  评论:(0)  加入收藏
对于各类开发语言来说,整数都有一个最大的位数,如果超过位数就无法显示或者操作了。其实,这也是一种精度越界之后产生的精度丢失问题。在我们的 PHP 代码中,最大的整数非常大,我...【详细内容】
2021-08-26  硬核项目经理    Tags:PHP   点击:(83)  评论:(0)  加入收藏
遵从所有教材以及各类数据结构相关的书书籍,我们先从线性表开始入门。今天这篇文章更偏概念,是关于有线性表的一个知识点的汇总。上文说过,物理结构是用于确定数据以何种方式存...【详细内容】
2021-07-19  硬核项目经理    Tags:线性表   点击:(94)  评论:(0)  加入收藏
一、开启IIS全部功能。二、部署PHP1.官网下载并解压PHP: https://windows.php.net/downloads/releases/2.将php.ini-development文件改为php.ini3.修改php.ini(1)去掉注释,并修...【详细内容】
2021-07-15  炘蓝火诗  今日头条  Tags:PHP环境   点击:(129)  评论:(0)  加入收藏
一、环境说明本文中使用本地VM虚机部署测试。OS:CentOS Linux release 7.8.2003 (Core)虚机配置:2核CPU、4G内存①系统为CentOS 7.8 x64最小化安装,部署前已完成系统初始化、...【详细内容】
2021-06-25  IT运维笔记  今日头条  Tags:PHP8.0.7   点击:(141)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条