所以我有一个位置搜索字段,我想接受几乎所有东西(城市,州和邮政编码),例如:
那里的任何组合...
从那时起,我将这些单词分成了一个带
的数组$inputs = preg_split("/[\s,-\/]+/", $input);
这给了我类似的东西
array(5) {
[0]=> string(4) "Some"
[1]=> string(4) "City"
[2]=> string(3) "New"
[3]=> string(4) "York"
[4]=> string(5) "88888"
}
然后我先找出邮政编码
foreach ($inputs as $key => $value) {
if (is_numeric($value) && strlen($value) == 5) {
$zip = $value;
unset($inputs[$key]);
}
}
注意unset()
现在我需要将状态名称与状态数据库相匹配。困境是一些州的名字中有多个单词(北卡罗来纳州,纽约)。
如何将我的$inputs
与州名和缩写相匹配,从我的数组中删除匹配的条件(我必须为下一个城市做同样的事情)?
我正在考虑尝试
$inputString = "'" . implode("','", $inputs) . "'";
$result = mysql_query("SELECT state_name
FROM states
WHERE state_name IN ({$inputString})
OR state_abbrev IN ({$inputString})");
但这并不能说明哪些内容匹配或适用于多字状态
编辑:
对于仇敌,我宁愿没有3个单独的领域。我认为这使用户体验变得复杂。我宁愿让服务器思考而不是他们,以最好地猜测他们尝试传达的位置。我也会有一个“高级”搜索,它将包含这些字段,但所有这些字段都占用了太多空间用于网站设计。
示例:
答案 0 :(得分:2)
您可以在address
表中添加一列,其中包含城市名称,州名称,邮政编码等的串联。然后在其上设置FULLTEXT
索引,并在其上运行整个输入字符串的全文搜索。
不确定这表现得如何。
答案 1 :(得分:0)
这就是我目前正在使用的,但有很多循环和查询,我怀疑它是高效的还是“非常准确地猜测”
function getLocations($input) {
$state = NULL;
$zip = NULL;
$input = strtoupper(trim($input));
$inputs = preg_split("/[^a-zA-Z0-9]+/", $input);
// Resolve zip code
foreach ($inputs as $key => $value) {
if (is_numeric($value) && strlen($value) == 5) {
$zip = $value;
unset($inputs[$key]);
}
}
$inputs = array_reverse($inputs);
$result = mysql_query("SELECT state_name, state_abbrev FROM states");
// Resolve state (one worded)
while ($row = mysql_fetch_assoc($result)) {
foreach ($inputs as $key => $value) {
if ($row['state_abbrev'] == $value || $row['state_name'] == $value) {
$state = $row['state_abbrev'];
unset($inputs[$key]);
return array(
'city' => "'" . implode(" ", array_reverse($inputs)) . "'",
'state' => "'" . $state . "'",
'zip' => "'" . $zip . "'"
);
}
}
}
// Resolve state (2/3 worded)
for ($i = 0; $i < count($inputs) - 1; $i++) {
$duoValue = @$inputs[$i + 1] . " " . @$inputs[$i];
if (count($inputs) > $i + 2) {
$trioValue = $inputs[$i + 2] . " " . $duoValue;
}
$result2 = mysql_query("SELECT state_name, state_abbrev FROM states") or die (mysql_error());
while ($row = mysql_fetch_assoc($result2)) {
if ($row['state_abbrev'] == $duoValue || $row['state_name'] == $duoValue) {
$state = $row['state_abbrev'];
unset($inputs[$i], $inputs[$i + 1]);
return array(
'city' => "'" . implode(" ", array_reverse($inputs)) . "'",
'state' => "'" . $state . "'",
'zip' => "'" . $zip . "'"
);
}
else if ($i < count($inputs) - 2) {
if ($row['state_abbrev'] == $trioValue || $row['state_name'] == $trioValue) {
$state = $row['state_abbrev'];
unset($inputs[$i], $inputs[$i + 1], $inputs[$i + 2]);
return array(
'city' => "'" . implode(" ", array_reverse($inputs)) . "'",
'state' => "'" . $state . "'",
'zip' => "'" . $zip . "'"
);
}
}
}
}
return array(
'city' => "'" . implode(" ", array_reverse($inputs)) . "'",
'state' => "'" . $state . "'",
'zip' => "'" . $zip . "'"
);
}
答案 2 :(得分:0)
我完全同意您的想法,即让用户轻松使用并在1个单输入框中显示所有地址信息。但是,每个用户可能会以不同的方式输入信息,并且很难找到涵盖每种情况的算法。最好的办法是看看是否有人已经这样做了,正如你所提到的,google有。幸运的是,他们有一个API来解决这个问题。
如果您使用Google地图地理编码器(https://developers.google.com/maps/documentation/geocoding/#GeocodingRequests),您基本上可以将任何合理地看起来像地址的内容传递给它,并且它将返回结构良好的地址结果。
Google的示例:https://google-developers.appspot.com/maps/documentation/javascript/examples/geocoding-simple
另一个例子 - 查找白宫:将此URL放在浏览器中: http://maps.googleapis.com/maps/api/geocode/json?address=1600%20pennsylvania%20ave%20washongton%20dc&sensor=false(注意我在这里故意拼写错误以显示API的容差)。
API调用返回一个非常有用的JSON对象:
{
"results" : [
{
"address_components" : [
{
"long_name" : "1600",
"short_name" : "1600",
"types" : [ "street_number" ]
},
{
"long_name" : "Pennsylvania Ave NW",
"short_name" : "Pennsylvania Ave NW",
"types" : [ "route" ]
},
{
"long_name" : "Washington",
"short_name" : "Washington",
"types" : [ "locality", "political" ]
},
{
"long_name" : "District of Columbia",
"short_name" : "DC",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "20502",
"short_name" : "20502",
"types" : [ "postal_code" ]
}
],
"formatted_address" : "1600 Pennsylvania Ave NW, Washington, DC 20502, USA",
"geometry" : {
"location" : {
"lat" : 38.89767770,
"lng" : -77.03651700000002
},
"location_type" : "ROOFTOP",
"viewport" : {
"northeast" : {
"lat" : 38.89902668029149,
"lng" : -77.03516801970852
},
"southwest" : {
"lat" : 38.89632871970850,
"lng" : -77.03786598029153
}
}
},
"partial_match" : true,
"types" : [ "street_address" ]
},
{
"address_components" : [
{
"long_name" : "1600",
"short_name" : "1600",
"types" : [ "street_number" ]
},
{
"long_name" : "Pennsylvania Ave NW",
"short_name" : "Pennsylvania Ave NW",
"types" : [ "route" ]
},
{
"long_name" : "Washington",
"short_name" : "Washington",
"types" : [ "locality", "political" ]
},
{
"long_name" : "District of Columbia",
"short_name" : "DC",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "20500",
"short_name" : "20500",
"types" : [ "postal_code" ]
}
],
"formatted_address" : "1600 Pennsylvania Ave NW, Washington, DC 20500, USA",
"geometry" : {
"location" : {
"lat" : 38.89871490,
"lng" : -77.03765550
},
"location_type" : "ROOFTOP",
"viewport" : {
"northeast" : {
"lat" : 38.90006388029150,
"lng" : -77.03630651970849
},
"southwest" : {
"lat" : 38.89736591970851,
"lng" : -77.03900448029150
}
}
},
"partial_match" : true,
"types" : [ "street_address" ]
},
{
"address_components" : [
{
"long_name" : "1600",
"short_name" : "1600",
"types" : [ "street_number" ]
},
{
"long_name" : "Pennsylvania Ave NW",
"short_name" : "Pennsylvania Ave NW",
"types" : [ "route" ]
},
{
"long_name" : "Washington",
"short_name" : "Washington",
"types" : [ "locality", "political" ]
},
{
"long_name" : "District of Columbia",
"short_name" : "DC",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "20004",
"short_name" : "20004",
"types" : [ "postal_code" ]
}
],
"formatted_address" : "1600 Pennsylvania Ave NW, Washington, DC 20004, USA",
"geometry" : {
"location" : {
"lat" : 38.89549710,
"lng" : -77.03008090000002
},
"location_type" : "ROOFTOP",
"viewport" : {
"northeast" : {
"lat" : 38.89684608029150,
"lng" : -77.02873191970852
},
"southwest" : {
"lat" : 38.89414811970850,
"lng" : -77.03142988029153
}
}
},
"partial_match" : true,
"types" : [ "street_address" ]
},
{
"address_components" : [
{
"long_name" : "1600",
"short_name" : "1600",
"types" : [ "street_number" ]
},
{
"long_name" : "Pennsylvania Ave SE",
"short_name" : "Pennsylvania Ave SE",
"types" : [ "route" ]
},
{
"long_name" : "Hill East",
"short_name" : "Hill East",
"types" : [ "neighborhood", "political" ]
},
{
"long_name" : "Washington",
"short_name" : "Washington",
"types" : [ "locality", "political" ]
},
{
"long_name" : "District of Columbia",
"short_name" : "DC",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "20003",
"short_name" : "20003",
"types" : [ "postal_code" ]
}
],
"formatted_address" : "1600 Pennsylvania Ave SE, Washington, DC 20003, USA",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 38.87865290,
"lng" : -76.98170180
},
"southwest" : {
"lat" : 38.87865220,
"lng" : -76.98170229999999
}
},
"location" : {
"lat" : 38.87865290,
"lng" : -76.98170180
},
"location_type" : "RANGE_INTERPOLATED",
"viewport" : {
"northeast" : {
"lat" : 38.88000153029150,
"lng" : -76.98035306970850
},
"southwest" : {
"lat" : 38.87730356970850,
"lng" : -76.98305103029151
}
}
},
"partial_match" : true,
"types" : [ "street_address" ]
}
],
"status" : "OK"
}
答案 3 :(得分:0)
一个可能的解决方案就是只需要一个用户的邮政编码,并使用http://www.zippopotam.us/的api来获取州和城市,并且不确定这是否符合你的ux设计你的寻求,但我已经使用jiery使用它们的api完成此操作,该api返回值为
的两个字段 $("#text-4edcd39ecca23").keyup(function (event) {
if (this.value.length === 5) {
var $citywrap = $("#fm-item-text-4edcd393cb50f");
var $city = $("#text-4edcd38744891");
var $statewrap = $("#fm-item-text-4edcd38744891");
var $state = $("#text-4edcd393cb50f");
var $zip = $('#text-4edcd39ecca23');
$.ajax({
url:"http://zippo-zippopotamus.dotcloud.com/us/" + $zip.val(),
cache:false,
dataType:"json",
type:"GET",
data:"us/" + $zip.val(),
success:function (result, success) {
// Remove Error Message if one is presant
$zip.parent().find('small').remove();
// US Zip Code Records Officially Map to only 1 Primary Location
var places = result['places'][0];
$city.val(places['place name']);
$state.val(places['state']);
$citywrap.slideDown();
$statewrap.slideDown();
},
error:function (result, success) {
$citywrap.slideUp();
$statewrap.slideUp();
$city.val('');
$state.val('');
$zip.parent().find('br').remove();
$zip.parent().find('small').remove();
$zip.after('<br /><small class="error">Sorry your zipcode was not reconized please try again</small>');
}
});
}
});