本文详解如何通过 Bing Maps 路由 REST API 获取两点间驾车距离(单位:km),并正确解析返回的 JSON 响应,避免常见解析失败问题(如 json_decode 返回 1),附完整 PHP 示例与关键注意事项。
本文详解如何通过 bing maps 路由
rest api
获取两点间驾车距离(单位:km),并正确解析返回的 json 响应,避免常见解析失败问题(如 `json_decode` 返回 `1`),附完整 php 示例与关键注意事项。
在构建预算估算类 Web 应用时,常需动态计算用户出发地与服务地址之间的实际驾驶距离(以公里为单位)。由于 Google Maps Platform 已全面商业化,而 Bing Maps 提供免费层级(含每月 125,000 次基础事务),成为中小型项目的高性价比替代方案。但其 REST API 返回的是结构化 JSON 数据,若未正确获取响应体或处理编码/错误格式,极易导致 json_decode() 失败(例如始终返回 1 —— 这通常是因传入了非字符串、布尔值 true 或空内容所致)。
以下为可落地的完整实现流程:
✅ 正确调用 Bing Maps 路由 API
首先确保 URL 构造规范(注意:必须使用 HTTPS,旧 HTTP 端点 http://dev.virtualearth.net 已弃用且不可用):
⚠️ 关键修正点:
使用 wp.0 和 wp.1(而非 wayPoint.1 / viaWaypoint.2)指定起点与终点;
必须启用 HTTPS;
地址需经 urlencode() 处理,避免空格、中文等导致请求失败;
travelMode=Driving 是默认值,可省略;optimize=distance 确保返回最短路径(非最快)。
✅ 安全发起 HTTP 请求并获取原始响应
推荐使用 cURL(比 file_get_contents() 更可控):
✅ 正确解析 JSON 并提取距离值
json_decode($response, true) 返回 null 或 1 的根本原因通常是:
$response 不是纯 JSON 字符串(例如混入 HTML 错误页、BOM 头、调试输出);
编码不一致(如 UTF-8 with BOM);
API 返回了错误 JSON(如 Bing 返回 HTML 错误页而非 JSON)。
因此,
务必先验证响应有效性
:
?
关键字段路径说明
:
Bing Maps 路由响应中,总距离(km)位于:
$data['resourceSets'][0]['resources'][0]['travelDistance']
(注意:travelDistance 单位即为请求参数 distanceUnit=km 所指定,无需换算)
⚠️ 注意事项与最佳实践
密钥安全
:切勿将 Bing Maps Key 硬编码在前端或公开代码中;应在服务端环境变量中管理。
配额监控
:免费层有调用次数限制,建议添加缓存(如 Redis)存储已计算过的地址对,减少重复请求。
地址标准化
:用户输入地址可能模糊,可先调用 Bing 的
Geocode API
获取精确经纬度,再用于路由计算,提升准确性。
错误兜底
:网络超时、地址无法解析、无可行路径等情况均需捕获并返回友好提示(如“暂无法计算该路线,请检查地址是否正确”)。
合规性
:遵守
Bing Maps Platform Terms of Use
,尤其禁止缓存地图瓦片或批量地理编码。
通过以上步骤,你即可稳定、可靠地集成 Bing Maps 路由能力,在零成本前提下为预算工具注入精准的距离计算逻辑。
$startAddress = urlencode("北京市朝阳区建国路8号");
$userAddress = urlencode("北京市海淀区中关村大街27号");
$bingKey = "YOUR_BING_MAPS_KEY"; // 替换为你的有效 Key
$url = "https://dev.virtualearth.net/REST/v1/Routes/Driving?" .
"wp.0={$startAddress}&" .
"wp.1={$userAddress}&" .
"optimize=distance&" .
"distanceUnit=km&" .
"key={$bingKey}";$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("Bing Maps API error: HTTP {$httpCode}");
}
// 验证响应是否为合法 JSON 字符串
if (empty($response) || !is_string($response)) {
throw new Exception("Empty or non-string response received");
}// 移除潜在 BOM 和空白
$response = trim($response);
if (substr($response, 0, 3) === "\xEF\xBB\xBF") {
$response = substr($response, 3);
}
// 尝试解码
$data = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new Exception("JSON decode failed: " . json_last_error_msg() . "\nRaw response: " . htmlspecialchars($response));
}
// 检查 Bing API 是否返回业务错误
if (!isset($data['resourceSets'][0]['resources'][0]['travelDistance'])) {
$error = $data['errorDetails'][0] ?? 'Unknown Bing Maps error';
throw new Exception("Bing Maps route calculation failed: {$error}");
}
$distanceKm = round($data['resourceSets'][0]['resources'][0]['travelDistance'], 1);
echo "两点间最短驾驶距离:{$distanceKm} 公里";