Laravel中使用LIKE谓词实现搜索时数组转字符串错误的解决
问题描述
开发带搜索功能的API,支持通过姓名或邮箱搜索用户,搜索关键词通过查询参数传递。不使用LIKE谓词时功能正常,但添加LIKE实现模糊搜索后,调用路由时Postman提示“数组转字符串”错误,求助解决方法。
相关代码
Search Controller
<?php namespace App\Http\Controllers; use App\Http\Resources\EmployeeListResource; use App\Talent\Search\SearchManager; use Illuminate\Http\Request; class SearchController extends Controller { public function __construct(private SearchManager $searchManager) { } public function show(Request $request) { $input=$request->query(); $search=$this->searchManager->search($input); return $search; } }
Search Manager
<?php namespace App\Talent\Search; use App\Talent\Employee\Model\Employee; use Illuminate\Database\Eloquent\Collection; class SearchManager { public function __construct(private Employee $employee) { } public function search(array $input): Collection|array { return $this->employee->with('employment:employee_id,current_position,work_schedule,team') ->whereIn('first_name','LIKE','%'.$input.'%')->orWhereIn('last_name','LIKE','%'.$input.'%') ->orWhereIn('email','LIKE','%'.$input.'%')->get(['id','first_name','last_name','email','status','avatar','contact_number']); } }
解决方案
错误原因
- 数组转字符串错误:
$request->query()返回所有查询参数的数组(比如?keyword=张三会得到['keyword' => '张三']),直接将数组拼接到字符串中触发PHP数组转字符串错误。 - 查询方法误用:
whereIn用于判断字段值是否存在于指定数组中(如whereIn('id', [1,2,3])),模糊搜索应使用where/orWhere方法。 - 逻辑条件风险:直接链式调用
orWhere会导致后续添加其他查询条件时逻辑混乱,需将多个“或”条件包裹在闭包中形成独立条件组。
修正代码
1. 修改Search Controller
提取具体搜索关键词参数,而非获取所有查询参数数组:
<?php namespace App\Http\Controllers; use App\Http\Resources\EmployeeListResource; use App\Talent\Search\SearchManager; use Illuminate\Http\Request; class SearchController extends Controller { public function __construct(private SearchManager $searchManager) { } public function show(Request $request) { // 获取搜索关键词,默认空字符串 $keyword = $request->query('keyword', ''); $search = $this->searchManager->search($keyword); return $search; } }
2. 修改Search Manager
调整查询方法,用闭包包裹“或”条件,并修正参数类型:
<?php namespace App\Talent\Search; use App\Talent\Employee\Model\Employee; use Illuminate\Database\Eloquent\Collection; class SearchManager { public function __construct(private Employee $employee) { } public function search(string $keyword): Collection { return $this->employee->with('employment:employee_id,current_position,work_schedule,team') ->where(function ($query) use ($keyword) { $query->where('first_name', 'LIKE', "%{$keyword}%") ->orWhere('last_name', 'LIKE', "%{$keyword}%") ->orWhere('email', 'LIKE', "%{$keyword}%"); }) ->get(['id','first_name','last_name','email','status','avatar','contact_number']); } }
额外建议
- SQL注入防护:上述写法Laravel会自动处理参数绑定,避免SQL注入;也可显式使用参数绑定增强安全性:
->where('first_name', 'LIKE', DB::raw('?'), ["%{$keyword}%"]) - 空关键词处理:若需在关键词为空时返回所有数据,可在
search方法中添加判断:if (empty($keyword)) { return $this->employee->with('employment:employee_id,current_position,work_schedule,team') ->get(['id','first_name','last_name','email','status','avatar','contact_number']); }
内容的提问来源于stack exchange,提问作者Bhabishya Portfilio
相关产品推荐
相关产品推荐

