全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

掌握 Laravel 查询构建器中的条件查询技巧

本文深入探讨了在 Laravel 8 中利用查询构建器(Query Builder)或 Eloquent 进行动态搜索的最佳实践。针对根据可选请求参数构建复杂查询的场景,文章详细介绍了如何使用 `when` 方法优雅地实现条件查询,避免冗余的 `if` 语句,从而编写出更简洁、可读性更强的代码。

在开发基于 Laravel 的应用程序时,经常需要根据用户提供的可选参数(例如搜索关键词、筛选条件等)动态构建数据库查询。传统的做法是使用一系列 if 语句来判断参数是否存在,然后有条件地向查询链中添加 where 子句。然而,这种方法在面对多个可选条件时,可能导致代码冗长且难以维护。Laravel 提供了一种更为优雅和强大的解决方案:when 方法。

动态查询构建的挑战

考虑一个常见的场景:用户可以通过 URL 查询字符串(如 ?q=john&gender=m)来搜索用户列表。如果 q 或 gender 参数不存在,则不应将其作为查询条件。

初始的尝试可能如下所示:

public function index (Request $request)
{
    $role = getRoleCode($request->role);
    $rolesQuery = Role::where('role', '=', $role); // 注意:这里应是 $rolesQuery 而非 $roles

    if ($request->q) {
        // 错误:$request->$q 是错误的变量引用方式
        $rolesQuery->where('name', 'like', "%$request->$q%");
    }

    if ($request->gender) {
        $rolesQuery->where('gender', '=', $request->gender);
    }

    // 在实际执行查询之前,可能需要将结果赋值给一个变量
    $roles = $rolesQuery->orderBy('id', 'desc')->paginate(20);

    return view('admin.users.index', [
        'roles' => $roles,
        // ... 其他视图数据
    ]);
}

上述代码中存在几个问题:

  1. 变量命名不一致,$roles 在条件语句中被当做查询构建器实例,但在最后又被赋值为分页结果。
  2. $request->$q 是一种错误的变量引用方式,正确的应是 $request->q 或 $request->input('q')。
  3. 虽然 if 语句可以实现条件查询,但当条件增多时,代码的层级和复杂度会增加,降低可读性。

优雅的解决方案:使用 when 方法

Laravel 的查询构建器和 Eloquent 模型都提供了 when 方法,用于实现条件性地向查询中添加子句。when 方法的签名如下:

when(mixed $value, callable $callback, callable $default = null): static

它接受三个参数:

  1. $value:一个用于判断条件的布尔值或可以被评估为布尔值的值。如果此值为 true(或“真值”),则执行第二个参数 $callback。
  2. $callback:一个闭包函数,它将接收当前查询构建器实例作为第一个参数,以及 $value 作为第二个参数(如果 $value 是一个非布尔值且为真)。
  3. $default (可选):如果 $value 为 false(或“假值”),则执行此闭包函数。

利用 when 方法,我们可以将上述动态查询重构为以下简洁且高效的形式:

role);

        $roles = Role::where('role', $roleCode)
            // 当 $request->input('q') 非空时,执行闭包添加 name 搜索条件
            ->when($request->input('q'), function ($query, $search) {
                return $query->where('name', 'like', '%' . $search . '%');
            })
            // 当 $request->input('gender') 非空时,执行闭包添加 gender 筛选条件
            ->when($request->input('gender'), function ($query, $gender) {
                return $query->where('gender', $gender);
            })
            ->orderBy('id', 'DESC')
            ->paginate(20);

        return view('admin.users.index', [
            'roles' => $roles,
            'role_name' => config('settings.roles')[$roleCode], // 假设配置存在
            'role_en_name' => $request->role,
            'q' => $request->input('q'),
            'gender' => $request->input('gender'),
        ]);
    }

    // 假设这是一个辅助函数,用于获取角色代码
    protected function getRoleCode($roleName)
    {
        // 实现根据角色名称获取角色代码的逻辑
        // 例如:
        switch ($roleName) {
            case 'supervisor': return 'SUP';
            case 'admin': return 'ADM';
            default: return 'USR';
        }
    }
}

代码解析:

  1. Role::where('role', $roleCode):这是所有查询的基础条件。
  2. ->when($request->input('q'), function ($query, $search) { ... }):
    • $request->input('q'):安全地从请求中获取 q 参数的值。如果 q 参数不存在或为空字符串,input() 方法将返回 null 或空字符串,这在布尔上下文中被评估为 false。
    • function ($query, $search) { ... }:这是一个闭包函数。
      • $query:代表当前的查询构建器实例。
      • $search:如果 $request->input('q') 的值是“真值”,那么 $search 将接收到 $request->input('q') 的实际值。
      • return $query->where('name', 'like', '%' . $search . '%');:在这个闭包中,我们向查询中添加了 name 字段的模糊搜索条件。务必从闭包中返回 $query 实例,以便继续链式调用。
  3. ->when($request->input('gender'), function ($query, $gender) { ... }):同理,这会根据 gender 参数的值添加精确匹配条件。
  4. ->orderBy('id', 'DESC')->paginate(20):最后,应用排序和分页。

注意事项与最佳实践

  • 使用 $request->input():始终建议使用 $request->input('param_name') 来获取请求参数,因为它比 $request->param_name 更健壮,可以处理 GET 和 POST 请求,并且在参数不存在时返回 null 而不是抛出错误。
  • 链式调用:when 方法的强大之处在于它保持了查询构建器的链式调用特性,使得代码流程清晰。
  • 闭包返回值:在 when 方法的闭包中,一定要返回修改后的 $query 实例,否则后续的链式操作将无法生效。
  • 可读性:when 方法显著提高了代码的可读性和简洁性,特别是当有多个可选条件时。
  • PHP 7.4+ 箭头函数:如果你的项目使用 PHP 7.4 或更高版本,可以使用箭头函数进一步简化闭包的写法,如示例答案中所示:fn ($query, $search) => $query->where('name', 'like', '%'. $search .'%')。

总结

Laravel 的 when 方法是处理动态条件查询的利器,它提供了一种优雅、高效且可读性强的方式来构建复杂的数据库查询。通过合理运用 when 方法,开发者可以避免冗余的 if 语句,使控制器代码更加简洁和专业,从而提升应用程序的可维护性和开发效率。掌握这一技巧对于任何 Laravel 开发者来说都至关重要。


# php  # laravel  # app  # switch  # NULL  # if  # 字符串  # 闭包  # function  # default  # input  # 数据库  # 重构  # 链式  # 可选  # 不存在  # 子句  # 多个  # 包中  # 这是一个  # 第二个  # 分页  # 所示 


相关文章: ,南京靠谱的征婚网站?  实例解析Array和String方法  如何挑选最适合建站的高性能VPS主机?  武清网站制作公司,天津武清个人营业执照注销查询系统网站?  建站主机是否等同于虚拟主机?  如何有效防御Web建站篡改攻击?  简单实现Android文件上传  宝塔新建站点报错如何解决?  C++如何将C风格字符串(char*)转换为std::string?(代码示例)  如何选择高效可靠的多用户建站源码资源?  如何在IIS7上新建站点并设置安全权限?  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  如何在阿里云部署织梦网站?  在线教育网站制作平台,山西立德教育官网?  深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?  如何快速搭建高效WAP手机网站吸引移动用户?  建站主机默认首页配置指南:核心功能与访问路径优化  金*站制作公司有哪些,金华教育集团官网?  潍坊网站制作公司有哪些,潍坊哪家招聘网站好?  韩国服务器如何优化跨境访问实现高效连接?  如何在宝塔面板创建新站点?  C#如何使用XPathNavigator高效查询XML  C++ static_cast和dynamic_cast区别_C++静态转换与动态类型安全转换  开封网站制作公司,网络用语开封是什么意思?  b2c电商网站制作流程,b2c水平综合的电商平台?  如何在Tomcat中配置并部署网站项目?  建站之星如何开启自定义404页面避免用户流失?  香港服务器WordPress建站指南:SEO优化与高效部署策略  如何在香港服务器上快速搭建免备案网站?  建站之星展会模版如何一键下载生成?  香港服务器选型指南:免备案配置与高效建站方案解析  合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?  如何高效生成建站之星成品网站源码?  头像制作网站在线制作软件,dw网页背景图像怎么设置?  在线ppt制作网站有哪些,请推荐几个好的课件下载的网站?  javascript基本数据类型及类型检测常用方法小结  如何用已有域名快速搭建网站?  香港服务器租用每月最低只需15元?  如何通过wdcp面板快速创建网站?  教学论文网站制作软件有哪些,写论文用什么软件 ?  如何制作一个表白网站视频,关于勇敢表白的小标题?  免费ppt制作网站,有没有值得推荐的免费PPT网站?  专业网站制作企业网站,如何制作一个企业网站,建设网站的基本步骤有哪些?  简历在线制作网站免费版,如何创建个人简历?  在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?  如何制作网站标识牌,动态网站如何制作(教程)?  如何获取PHP WAP自助建站系统源码?  php条件判断怎么写_ifelse和switchcase的使用区别【对比】  音响网站制作视频教程,隆霸音响官方网站?  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。