2011-02-02 4 views
0

Google Geocoder API에서 반환 된 JSON 문자열을 읽고 구문 분석하려는 PHP 스크립트가 있습니다. 스크립트는 대부분의 주소에서 제대로 작동하지만 Google 지오 코더 API가 주어진 주소에 대해 여러 결과를 반환하는 경우가 있습니다. 또한 지오 코더는 다음과 같은 JSON 문자열을 반환Geocoder에서 여러 결과가 반환되는 경우 PHP 스크립트가 Google Maps Geocoder API에서 반환 한 JSON을 구문 분석하지 못합니다.

array(2) { ["status"]=> string(2) "OK" ["results"]=> array(1) { [0]=> array(4) { ["types"]=> array(1) { [0]=> string(14) "street_address" } ["formatted_address"]=> string(37) "115 Chestnut St, Upton, MA 01568, USA" ["address_components"]=> array(8) { [0]=> array(3) { ["long_name"]=> string(3) "115" ["short_name"]=> string(3) "115" ["types"]=> array(1) { [0]=> string(13) "street_number" } } [1]=> array(3) { ["long_name"]=> string(11) "Chestnut St" ["short_name"]=> string(11) "Chestnut St" ["types"]=> array(1) { [0]=> string(5) "route" } } [2]=> array(3) { ["long_name"]=> string(5) "Upton" ["short_name"]=> string(5) "Upton" ["types"]=> array(2) { [0]=> string(8) "locality" [1]=> string(9) "political" } } [3]=> array(3) { ["long_name"]=> string(5) "Upton" ["short_name"]=> string(5) "Upton" ["types"]=> array(2) { [0]=> string(27) "administrative_area_level_3" [1]=> string(9) "political" } } [4]=> array(3) { ["long_name"]=> string(9) "Worcester" ["short_name"]=> string(9) "Worcester" ["types"]=> array(2) { [0]=> string(27) "administrative_area_level_2" [1]=> string(9) "political" } } [5]=> array(3) { ["long_name"]=> string(13) "Massachusetts" ["short_name"]=> string(2) "MA" ["types"]=> array(2) { [0]=> string(27) "administrative_area_level_1" [1]=> string(9) "political" } } [6]=> array(3) { ["long_name"]=> string(13) "United States" ["short_name"]=> string(2) "US" ["types"]=> array(2) { [0]=> string(7) "country" [1]=> string(9) "political" } } [7]=> array(3) { ["long_name"]=> string(5) "01568" ["short_name"]=> string(5) "01568" ["types"]=> array(1) { [0]=> string(11) "postal_code" } } } ["geometry"]=> array(4) { ["location"]=> array(2) { ["lat"]=> float(42.1476896) ["lng"]=> float(-71.5863099) } ["location_type"]=> string(18) "RANGE_INTERPOLATED" ["viewport"]=> array(2) { ["southwest"]=> array(2) { ["lat"]=> float(42.1445379) ["lng"]=> float(-71.5894495) } ["northeast"]=> array(2) { ["lat"]=> float(42.1508332) ["lng"]=> float(-71.5831542) } } ["bounds"]=> array(2) { ["southwest"]=> array(2) { ["lat"]=> float(42.1476815) ["lng"]=> float(-71.5863099) } ["northeast"]=> array(2) { ["lat"]=> float(42.1476896) ["lng"]=> float(-71.5862938) } } } } } } 
array(2) { ["lat"]=> float(42.1476896) ["lng"]=> float(-71.5863099) } 

을 :

$mGeoFile = fopen("http://maps.googleapis.com/maps/api/geocode/json?address=" . str_replace(" ", "+", $mAddress0) . "&sensor=false", "r");  
$mGeoFileJSON = fread($mGeoFile, 10000); 
fclose($mGeoFile); 
$mGeocode_array = json_decode($mGeoFileJSON, true); 

var_dump($mGeocode_array); 
echo "<br />"; 
var_dump($mGeocode_array['results'][0]['geometry']['location']); 

이 ($ mAddress0 전달) "(115) 밤 거리 업톤, MA"를 인쇄합니다

내 코드입니다 "115 Chestnut Street Upton, MA"에 대해서

{ 
    "status": "OK", 
    "results": [ { 
    "types": [ "street_address" ], 
    "formatted_address": "115 Chestnut St, Upton, MA 01568, USA", 
    "address_components": [ { 
     "long_name": "115", 
     "short_name": "115", 
     "types": [ "street_number" ] 
    }, { 
     "long_name": "Chestnut St", 
     "short_name": "Chestnut St", 
     "types": [ "route" ] 
    }, { 
     "long_name": "Upton", 
     "short_name": "Upton", 
     "types": [ "locality", "political" ] 
    }, { 
     "long_name": "Upton", 
     "short_name": "Upton", 
     "types": [ "administrative_area_level_3", "political" ] 
    }, { 
     "long_name": "Worcester", 
     "short_name": "Worcester", 
     "types": [ "administrative_area_level_2", "political" ] 
    }, { 
     "long_name": "Massachusetts", 
     "short_name": "MA", 
     "types": [ "administrative_area_level_1", "political" ] 
    }, { 
     "long_name": "United States", 
     "short_name": "US", 
     "types": [ "country", "political" ] 
    }, { 
     "long_name": "01568", 
     "short_name": "01568", 
     "types": [ "postal_code" ] 
    } ], 
    "geometry": { 
     "location": { 
     "lat": 42.1476896, 
     "lng": -71.5863099 
     }, 
     "location_type": "RANGE_INTERPOLATED", 
     "viewport": { 
     "southwest": { 
      "lat": 42.1445379, 
      "lng": -71.5894495 
     }, 
     "northeast": { 
      "lat": 42.1508332, 
      "lng": -71.5831542 
     } 
     }, 
     "bounds": { 
     "southwest": { 
      "lat": 42.1476815, 
      "lng": -71.5863099 
     }, 
     "northeast": { 
      "lat": 42.1476896, 
      "lng": -71.5862938 
     } 
     } 
    } 
    } ] 
} 

다음과 같은 주소로 문제가 발생합니다. S (50) 프랭클린 스트리트 보스턴, MA있는 구글 지오 코더 API 반환 :

{ 
    "status": "OK", 
    "results": [ { 
    "types": [ "street_address" ], 
    "formatted_address": "50 Franklin St, Boston, MA 02110, USA", 
    "address_components": [ { 
     "long_name": "50", 
     "short_name": "50", 
     "types": [ "street_number" ] 
    }, { 
     "long_name": "Franklin St", 
     "short_name": "Franklin St", 
     "types": [ "route" ] 
    }, { 
     "long_name": "Boston", 
     "short_name": "Boston", 
     "types": [ "locality", "political" ] 
    }, { 
     "long_name": "Boston", 
     "short_name": "Boston", 
     "types": [ "administrative_area_level_3", "political" ] 
    }, { 
     "long_name": "Suffolk", 
     "short_name": "Suffolk", 
     "types": [ "administrative_area_level_2", "political" ] 
    }, { 
     "long_name": "Massachusetts", 
     "short_name": "MA", 
     "types": [ "administrative_area_level_1", "political" ] 
    }, { 
     "long_name": "United States", 
     "short_name": "US", 
     "types": [ "country", "political" ] 
    }, { 
     "long_name": "02110", 
     "short_name": "02110", 
     "types": [ "postal_code" ] 
    } ], 
    "geometry": { 
     "location": { 
     "lat": 42.3556540, 
     "lng": -71.0585261 
     }, 
     "location_type": "ROOFTOP", 
     "viewport": { 
     "southwest": { 
      "lat": 42.3525064, 
      "lng": -71.0616737 
     }, 
     "northeast": { 
      "lat": 42.3588016, 
      "lng": -71.0553785 
     } 
     } 
    } 
    }, { 
    "types": [ "street_address" ], 
    "formatted_address": "50 Franklin St, Boston, MA 02122, USA", 
    "address_components": [ { 
     "long_name": "50", 
     "short_name": "50", 
     "types": [ "street_number" ] 
    }, { 
     "long_name": "Franklin St", 
     "short_name": "Franklin St", 
     "types": [ "route" ] 
    }, { 
     "long_name": "Boston", 
     "short_name": "Boston", 
     "types": [ "locality", "political" ] 
    }, { 
     "long_name": "Boston", 
     "short_name": "Boston", 
     "types": [ "administrative_area_level_3", "political" ] 
    }, { 
     "long_name": "Suffolk", 
     "short_name": "Suffolk", 
     "types": [ "administrative_area_level_2", "political" ] 
    }, { 
     "long_name": "Massachusetts", 
     "short_name": "MA", 
     "types": [ "administrative_area_level_1", "political" ] 
    }, { 
     "long_name": "United States", 
     "short_name": "US", 
     "types": [ "country", "political" ] 
    }, { 
     "long_name": "02122", 
     "short_name": "02122", 
     "types": [ "postal_code" ] 
    } ], 
    "geometry": { 
     "location": { 
     "lat": 42.2871370, 
     "lng": -71.0400105 
     }, 
     "location_type": "ROOFTOP", 
     "viewport": { 
     "southwest": { 
      "lat": 42.2839894, 
      "lng": -71.0431581 
     }, 
     "northeast": { 
      "lat": 42.2902846, 
      "lng": -71.0368629 
     } 
     } 
    } 
    }, { 
    "types": [ "street_address" ], 
    "formatted_address": "50 Franklin St, Boston, MA 02129, USA", 
    "address_components": [ { 
     "long_name": "50", 
     "short_name": "50", 
     "types": [ "street_number" ] 
    }, { 
     "long_name": "Franklin St", 
     "short_name": "Franklin St", 
     "types": [ "route" ] 
    }, { 
     "long_name": "Boston", 
     "short_name": "Boston", 
     "types": [ "locality", "political" ] 
    }, { 
     "long_name": "Boston", 
     "short_name": "Boston", 
     "types": [ "administrative_area_level_3", "political" ] 
    }, { 
     "long_name": "Suffolk", 
     "short_name": "Suffolk", 
     "types": [ "administrative_area_level_2", "political" ] 
    }, { 
     "long_name": "Massachusetts", 
     "short_name": "MA", 
     "types": [ "administrative_area_level_1", "political" ] 
    }, { 
     "long_name": "United States", 
     "short_name": "US", 
     "types": [ "country", "political" ] 
    }, { 
     "long_name": "02129", 
     "short_name": "02129", 
     "types": [ "postal_code" ] 
    } ], 
    "geometry": { 
     "location": { 
     "lat": 42.3785674, 
     "lng": -71.0668132 
     }, 
     "location_type": "RANGE_INTERPOLATED", 
     "viewport": { 
     "southwest": { 
      "lat": 42.3754150, 
      "lng": -71.0699535 
     }, 
     "northeast": { 
      "lat": 42.3817103, 
      "lng": -71.0636583 
     } 
     }, 
     "bounds": { 
     "southwest": { 
      "lat": 42.3785579, 
      "lng": -71.0668132 
     }, 
     "northeast": { 
      "lat": 42.3785674, 
      "lng": -71.0667986 
     } 
     } 
    } 
    }, { 
    "types": [ "street_address" ], 
    "formatted_address": "50 Franklin St, Boston, MA 02136, USA", 
    "address_components": [ { 
     "long_name": "50", 
     "short_name": "50", 
     "types": [ "street_number" ] 
    }, { 
     "long_name": "Franklin St", 
     "short_name": "Franklin St", 
     "types": [ "route" ] 
    }, { 
     "long_name": "Boston", 
     "short_name": "Boston", 
     "types": [ "locality", "political" ] 
    }, { 
     "long_name": "Boston", 
     "short_name": "Boston", 
     "types": [ "administrative_area_level_3", "political" ] 
    }, { 
     "long_name": "Suffolk", 
     "short_name": "Suffolk", 
     "types": [ "administrative_area_level_2", "political" ] 
    }, { 
     "long_name": "Massachusetts", 
     "short_name": "MA", 
     "types": [ "administrative_area_level_1", "political" ] 
    }, { 
     "long_name": "United States", 
     "short_name": "US", 
     "types": [ "country", "political" ] 
    }, { 
     "long_name": "02136", 
     "short_name": "02136", 
     "types": [ "postal_code" ] 
    } ], 
    "geometry": { 
     "location": { 
     "lat": 42.2526044, 
     "lng": -71.1332635 
     }, 
     "location_type": "RANGE_INTERPOLATED", 
     "viewport": { 
     "southwest": { 
      "lat": 42.2494625, 
      "lng": -71.1364052 
     }, 
     "northeast": { 
      "lat": 42.2557577, 
      "lng": -71.1301100 
     } 
     }, 
     "bounds": { 
     "southwest": { 
      "lat": 42.2526044, 
      "lng": -71.1332635 
     }, 
     "northeast": { 
      "lat": 42.2526158, 
      "lng": -71.1332517 
     } 
     } 
    }, 
    "partial_match": true 
    } ] 
} 

그리고 내 스크립트 반환 :

NULL 
NULL 

에 갈 수있는 무엇을 어떤 아이디어가? 감사!

답변

2

응답이 10K자를 초과 할 가능성이 있습니다.이 경우 유효하지 않은 JSON 문자열을 디코딩하려고합니다. 해독하기 전에 전체 스트림을 읽어야합니다. 가장 간단한 방법은 fopen/fread/fclose 대신 file_get_contents을 사용하는 것입니다. 장기적으로 당신은 컬로 전환해야합니다.

+0

감사합니다. @Maerlyn, 실제로 파일 크기를 1,000,000과 비슷하게 설정했습니다. 그러나이 제안은 효과가 있습니다. :) –

+1

증상 만 치료합니다. 이유는 없습니다. 단기간 동안 만 좋고,'allow_url_fopen'이 비활성화 된 서버로 이동할 때마다 다시 물러납니다. – Maerlyn

0

나를 위해 문자열이 완벽하게 디코딩됩니다. 아마도 응답이 UTF-8로 인코딩되고 문자열에 B.O.M (Byte Order Mark) 문자가있을 수 있습니다. 이 경우 문자열은 JSON 형식 구조가 아닙니다 (RFC 4627 참조).

그의 자리에서 나는 이것이 문제인지 알아보기 위해 몇 줄을 더 쓸 것이다. CCC inna bynary 문자열을 포장하는 B.O.M 문자를 제거 할 수 있습니다. 이 함수를 재귀 적으로 호출하십시오.

function removeBOM($str=""){ 
     if(substr($str, 0,3) == pack("CCC",0xef,0xbb,0xbf)) { 
       $str=substr($str, 3); 
     } 
     return $str; 
}