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

具体问题具体分析!代码实现基于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);

}

}

})

}

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • CREATE TABLE IF NOT EXISTS ecs_order_info (order_id mediu...
    cookie口阅读 15,660评论 0 16
  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,283评论 0 10
  • <?php /** * 常用函数库 * */ class Core_Fun { /** * 对变量进行反...
    寻梦xunm阅读 501评论 0 0
  • http://python.jobbole.com/85231/ 关于专业技能写完项目接着写写一名3年工作经验的J...
    燕京博士阅读 7,545评论 1 118
  • 早上醒来想起一个梦,梦见我的那几个调皮捣蛋的学生被施了咒,还被封印了记忆,说拿橡皮擦脸就能擦出来原型,擦一个小孩的...
    拜泉0610陈晨阅读 175评论 0 1