Laravel 11运费查询:起终点互换搜索及结果匹配问题排查
问题分析与解决方案
问题根源
- 表单未做必填校验:默认选项未设置
value属性,且无必填约束,用户可能提交空值,导致查询匹配到数据库中的空值记录。 - 查询逻辑缺乏参数校验:未验证
origin和destination是否为有效城市ID,无效值可能触发意外匹配。 - GET请求冗余携带
@csrf:CSRF令牌仅针对修改类请求(POST/PUT/DELETE),GET请求无需该字段。
解决方案
1. 修复搜索表单
添加必填校验、正确设置默认选项值,并移除冗余的@csrf:
<form action="{{ url('rates') }}" method="GET"> <div class="form-row align-items-center row"> <div class="col-md-5"> <label>Origin</label> <select class="form-control single-select-field" name="origin" required> <option value="" selected>Origin...</option> @foreach ($cities as $city) <option value="{{ $city->id }}">{{ $city->id}}</option> @endforeach </select> </div> <div class="col-md-5"> <label>Destination</label> <select class="form-control single-select-field" name="destination" required> <option value="" selected>Destination...</option> @foreach ($cities as $city) <option value="{{ $city->id }}">{{ $city->id }}</option> @endforeach </select> </div> <div class="col-md-6 my-3"> <button type="submit" class="btn btn-warning btn-block">Check Rates</button> </div> </div> </form>
2. 完善控制器查询逻辑
添加参数校验,确保查询仅针对有效城市ID,同时明确双向查询的逻辑:
use Illuminate\Http\Request; public function checkRates(Request $request) { // 验证参数有效性:必须为存在的城市ID $validated = $request->validate([ 'origin' => 'required|integer|exists:cities,id', 'destination' => 'required|integer|exists:cities,id', ]); $origin = $validated['origin']; $destination = $validated['destination']; // 闭包包裹确保OR逻辑的正确性 $result = RouteModel::where(function ($query) use ($origin, $destination) { $query->where('origin', $origin) ->where('destination', $destination) ->orWhere('origin', $destination) ->where('destination', $origin); })->first(); // 无结果时返回null或自定义响应 return $result ?? response()->json(['message' => 'No rate found'], 404); }
3. 数据库数据校验
确认RouteModel对应的表中:
origin和destination字段为整数类型- 不存在空值或无效ID的记录
- 避免同时存在
A→B和B→A的重复记录(若需求是同一组合仅存一条)
内容的提问来源于stack exchange,提问作者Edi Prasetyo
相关产品推荐
相关产品推荐

