经纬度验证需用between:-90,90和between:-180,180,配合nullable;推荐自定义Rule类结合is_numeric与范围判断防非法格式;嵌套和数组字段用点号和通配符;无需正则限制小数位,应在响应层控制精度。

验证经纬度字段是否在合法数值范围内
直接用 Laravel 的 between 规则就能搞定,但必须注意:纬度是 -90 到 90,经度是 -180 到 180,不能反也不能漏负号。很多人写成 between:0,90 就把南纬和西经全拦掉了。
- 纬度(
latitude)应校验between:-90,90 - 经度(
longitude)应校验between:-180,180 - 如果字段允许为空,加
nullable,但别加在between前面——Laravel 会跳过后续规则,推荐写成nullable|between:-90,90 - 前端传字符串(如
"39.9042")也没问题,Laravel 验证器会自动 cast 成 float
用自定义 Rule 类做更严格的经纬度格式校验
单纯数值范围不够:比如 999.999 过了 between:-90,90?不会,但它根本不是合法纬度。真正要防的是「看起来像数字、实则超精度或非法格式」的输入,比如带空格、科学计数法、NaN。这时候得上自定义 Rule。
- 运行
php artisan make:rule ValidLatitude,在passes()里用is_numeric($value)+ 范围判断双保险 - 别用
filter_var($value, FILTER_VALIDATE_FLOAT)—— 它接受1e2这种,而地理坐标不用科学计数法 - 示例逻辑:
return is_numeric($value) && $value >= -90 && $value <= 90;
- 同理建
ValidLongitude,范围换成 -180 到 180
API 请求体里字段名不叫 latitude/longitude 怎么办
实际项目里字段名可能是 lat/lng、coord_x/coord_y,甚至嵌套在 location 数组里。验证规则得跟着结构走,否则 between 直接失效。
- 扁平字段(如
lat):规则写'lat' => 'required|between:-90,90' - 嵌套字段(如
location.lat):规则键名必须带点,写成'location.lat' => 'required|between:-90,90' - 数组字段(如
points.*.lat):用通配符,'points.*.lat' => 'required|between:-90,90' - 别在
rules()方法里硬写死字段名——提取成常量或配置项,换字段时只改一处
为什么不用正则校验经纬度小数位数
有人想用正则限制「最多 6 位小数」,比如 regex:/^-?\d{1,3}(\.\d{1,6})?$/。这看似严谨,其实没必要,还容易出错。
- GPS 设备、地图 API 返回的坐标小数位数不统一,高德可能给 13 位,Leaflet 默认显示 5 位,后端不该卡位数
- PHP 浮点数精度本身有限,
floatval("39.90420000000001")和39.9042在比较时可能被当作相等,正则反而制造假性严格 - 真要控制输出精度,放在响应层(
number_format()或 cast),不在验证层 - 唯一需要正则的场景是:字段混入非数字字符(如
"39.9042°N"),那就先用trim()和filter_var(..., FILTER_SANITIZE_NUMBER_FLOAT)预处理


















