美文网首页
实现地址自动识别实例(PHP)

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

作者: PHP学习君 | 来源:发表于2019-06-14 13:24 被阅读0次

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

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

    UsersController控制器

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

    /**@varUserRepository */

    private$userRepository;

    publicfunction__construct(UsersRepository $userRepo)

    {

    $this->userRepository = $userRepo;

    }

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

    /**

    * Function:地址识别

    * Author:cyw0413

    *@paramRequest $request

    *@returnIlluminateContractsRoutingResponseFactory|IlluminateHttpResponse|

    * LaravelLumenHttpResponseFactory|SymfonyComponentHttpFoundationResponse

    */

    publicfunctiongetDiscern(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();

    returnresponse(['code'=>0,'msg'=>$msg]);

    }

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

    }

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

    /**

    * Function:识别地址

    * Author:cyw0413

    */

    publicfunctiongetDiscern($discernDel)

    {

    if(empty($discernDel)) {

    thrownewException("请传入要识别的地址");

    }

    $discernDel_left = explode ('[', $discernDel);

    if(!isset($discernDel_left[1])) {

    thrownewException("你填写的地址规则错误,手机号码应该用[]");

    }

    $discernDel_right = explode (']', $discernDel_left[1]);

    if(!isset($discernDel_right[1]) ||empty($discernDel_right[1])) {

    thrownewException("你填写的地址规则错误,手机号码应该用[]");

    }

    $name = $discernDel_left[0];

    if(empty($name)) {

    thrownewException("你填写的姓名有误!");

    }

    $mobile = $discernDel_right[0];

    if(empty($mobile) || checkMobile($mobile) ==0) {

    thrownewException("你填写的手机号码格式有误!");

    }

    $address = trim ($discernDel_right[1]);

    if(empty($address)) {

    thrownewException("你填写的地址不能为空");

    }

    $var_address =$this->getAddressArrar($address);

    $var_address['name'] = $name;

    $var_address['mobile'] = $mobile;

    return$var_address;

    }

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

    /**

    * Function:地址的处理

    * Author:cyw0413

    *@param$address

    *@returnarray

    *@throwsException

    */

    functiongetAddressArrar($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'])){

    thrownewException("请正确填写省份(市辖区)");

    }

    // 查找城市-第二级地区

    $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{

    //省份不填,报错误

    thrownewException("省份没填写,请检查");

    }

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

    }

    /**

    * 匹配正确的城市地址

    *@param$address

    *@param$city_list

    *@paramint $force

    *@paramint $str_len

    *@returnarray

    **/

    functioncheckAddress($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

    *@returnarray

    **/

    functiongetAddressInfo($address, $province, $city, $district){

    // 查找最后出现的地址 - 截取详细信息

    if(!isset($province['region_name'])){

    thrownewException("请检查并正确填写省份(市辖区)");

    }

    if(!isset($city['region_name'])){

    thrownewException("请检查并正确填写城市");

    }

    if(!isset($district['region_name'])){

    thrownewException("请检查并正确填写区域(县/区/镇)");

    }

    $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'])){

    thrownewException("详细地址不存在,请检查");

    }

    return$address = [

    'province'=> $province['region_code'],

    'city'=> $city['region_code'],

    'district'=> $district['region_code'],

    'info'=> $area['info']

    ];

    }

    前端html部分代码

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

    {!! Form::label('discern','自动识别地址:',['class'=>'control-label col-sm-2']) !!}

    {!! Form::textarea('discern','', ['class'=>'form-textarea form-control form-discern','rows'=> 3]) !!}

    提交识别

    *查看模板

    jquery代码部分

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

    /**

    * 地址识别

    * @returns {boolean}

    */

    functiongetDiscern(){

    vardiscernDel = $(".form-discern").val();

    if(!discernDel){

    alert("请输入要识别的地址");

    returnfalse;

    }

    $.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);

    }

    }

    })

    }

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

    相关文章

      网友评论

          本文标题:实现地址自动识别实例(PHP)

          本文链接:https://www.haomeiwen.com/subject/bswufctx.html