Laravel 数据库操作返回及其相关操作

laravel中数据库查询

laravel中数据库查询方式:

  • 原生SQL查询: DB::select('select * from users where active = 1')
  • 查询构建器: DB::tables('users')->where('xxx')->get()
  • Eloquent ORM 查询: User::where('xxx')->get()

详解

原生SQL查询

原生查询只能使用 DB::select()查询, 方法始终返回结果的 array, 也就是说, 可能返回: [], [stdClass], 没有单条查询.

如果说要强制将stdclass换成关联数组, 需要修改database.php配置 'options' => [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]

查询构建器

  • 查询构造器的方法first()通常返回 NULL / stdClass, 注意不能直接->toArray(), 需要进行is_null判断
  • 查询构造器的方法get()通常返回 Collection(stdClass), 空集合必须使用 $collection->isEmpty() 判断
  • 集合中的 Collection(stdClass)->toArray() 方法返回 [stdClass], 注意里面的stdClass不能被转化成关联数组

注意第三点, 不能转化成关联数组, 因为 toArray() 源代码中, 实现了Arrayable接口的才会转化成关联数组.

Eloquent ORM 查询

  • 查询构造器的方法first()通常返回 NULL / 模型, 注意不能直接->toArray(), 需要进行is_null判断
  • 查询构造器的方法get()通常返回 Collection(模型), 空集合必须使用 $collection->isEmpty() 判断
  • 集合中的 Collection(模型)->toArray() 方法返回 [关联数组], 注意里面的stdClass不能被转化成关联数组
  • 在ORM中提供了丰富的: 访问器(getFooAttribute), 修改器(setFooAttribute), 属性转化(casts), 追加属性($appends) 等

其他问题

  • 查询构建器通常比ORM性能更好, 因为其更轻量级
  • 集合类提供了强大且流畅的方法(如 map, filter, reduce)处理数据, 优先使用集合处理
// Collection(stdClass) 转化成关联数组
$users = DB::table('users')->get();
$usersArray = $users->map(function ($user) {
    return (array) $user; // 将每个 stdClass 对象强制转换为数组, 遍历1
})->toArray(); // 最后将整个集合也转换为数组, 遍历2
// 或者
$usersArray = $users->all(); // 获取底层数组的引用
foreach ($usersArray as &$user) {
    $user = (array) $user; // 直接修改数组中的每个元素
}


laravel集合常用方法

在 Laravel 中,集合(Collection)是处理数组数据的核心工具,封装了大量实用方法,极大简化了数据处理逻辑。以下是开发中使用频率最高的集合方法,按使用场景分类说明:

一、基础操作(获取/转换数据)

  1. all()
    返回集合底层的原生数组,常用于需要将集合转换为普通数组的场景(如接口返回、原生函数参数)。

    $collection = collect([1, 2, 3]);
    $array = $collection->all(); // [1, 2, 3]
  2. toArray()
    将集合(包括嵌套集合)转换为关联数组,与 all() 的区别是:toArray() 会递归转换所有嵌套集合,而 all() 仅返回顶层数组。

    $users = User::get(); // 模型集合
    $usersArray = $users->toArray(); // 所有用户转为关联数组(含嵌套关联)
  3. first() / last()

    • first():返回集合第一个元素(可传回调筛选条件)。
    • last():返回集合最后一个元素(可传回调筛选条件)。
      $collection = collect([1, 2, 3, 4]);
      $first = $collection->first(); // 1
      $lastEven = $collection->last(fn($item) => $item % 2 == 0); // 4
  4. pluck()
    提取集合中指定字段的值,返回新集合(类似“取列”操作),常用于获取 ID 列表、名称列表等。

    $users = User::get();
    $userIds = $users->pluck('id'); // 集合:[1, 2, 3, ...]
    $idToName = $users->pluck('name', 'id'); // 集合:[1 => '张三', 2 => '李四', ...]

二、筛选与转换

  1. filter()
    根据回调条件筛选元素,保留返回 true 的元素,类似“过滤”操作。

    $numbers = collect([1, 2, 3, 4, 5]);
    $evenNumbers = $numbers->filter(fn($num) => $num % 2 == 0); // [2, 4]
  2. map()
    遍历集合并通过回调转换每个元素,返回新集合(不改变原集合),常用于数据格式化。

    $users = collect([
        ['name' => '张三', 'age' => 20],
        ['name' => '李四', 'age' => 25]
    ]);
    $formatted = $users->map(fn($user) => "{$user['name']}({$user['age']}岁)");
    // 结果:['张三(20岁)', '李四(25岁)']
  3. where()
    根据键值对筛选元素(类似数据库 where),支持简单条件匹配。

    $users = collect([
        ['name' => '张三', 'age' => 20],
        ['name' => '李四', 'age' => 25]
    ]);
    $adults = $users->where('age', '>=', 22); // 筛选年龄≥22的用户

三、判断与统计

  1. count()
    返回集合元素的数量,等同于 $collection->all() 后的 count(),但更便捷。

    $collection = collect([1, 2, 3]);
    $count = $collection->count(); // 3
  2. isEmpty() / isNotEmpty()

    • isEmpty():判断集合是否为空(无元素)。
    • isNotEmpty():判断集合是否非空(有元素),常用于条件判断。
      $users = User::where('status', 0)->get();
      if ($users->isEmpty()) {
        // 没有符合条件的用户
      }
  3. contains()
    判断集合是否包含指定元素(可传值或回调条件)。

     $collection = collect(['apple', 'banana', 'orange']);
     $hasBanana = $collection->contains('banana'); // true
    
     $users = collect([['name' => '张三'], ['name' => '李四']]);
     $hasZhang = $users->contains('name', '张三'); // true

四、排序与分组

  1. sort() / sortBy() / sortByDesc()

    • sort():按元素值排序(默认升序,对数字/字符串有效)。
    • sortBy():按指定键排序(升序)。
    • sortByDesc():按指定键排序(降序)。
      $users = collect([
        ['name' => '张三', 'age' => 25],
        ['name' => '李四', 'age' => 20]
      ]);
      $sortedByAge = $users->sortBy('age'); // 按年龄升序:李四(20)、张三(25)
  2. groupBy()
    按指定键对集合分组,返回嵌套集合(键为分组值,值为对应元素集合),常用于分类展示数据。

    $posts = collect([
        ['category' => '技术', 'title' => 'Laravel入门'],
        ['category' => '技术', 'title' => 'PHP性能优化'],
        ['category' => '生活', 'title' => '旅行攻略']
    ]);
    $grouped = $posts->groupBy('category'); 
    // 结果:['技术' => [...], '生活' => [...]]

五、链式操作与其他高频方法

  1. each()
    遍历集合执行回调(无返回值),类似 foreach,但支持链式调用。

    User::get()->each(function ($user) {
        $user->last_login = now();
        $user->save();
    });
  2. sum() / avg()

    • sum():计算指定字段或元素的总和。
    • avg():计算指定字段或元素的平均值。
      $orders = Order::get();
      $totalAmount = $orders->sum('amount'); // 总金额
      $avgAmount = $orders->avg('amount'); // 平均金额
  3. flatMap()
    map() 转换元素,再将结果“展平”为一维集合(常用于处理嵌套数组)。

    $users = collect([
        ['name' => '张三', 'hobbies' => ['读书', '运动']],
        ['name' => '李四', 'hobbies' => ['游戏', '音乐']]
    ]);
    $allHobbies = $users->flatMap(fn($user) => $user['hobbies']);
    // 结果:['读书', '运动', '游戏', '音乐'](一维集合)

总结

这些方法覆盖了日常开发中 数据筛选、转换、统计、排序、分组 等核心场景。Laravel 集合的强大之处在于支持 链式调用,可以组合多个方法高效处理数据,例如:

$activeUserNames = User::get()
    ->where('status', 1) // 筛选活跃用户
    ->sortByDesc('created_at') // 按创建时间倒序
    ->pluck('name'); // 提取用户名

熟练掌握这些方法能极大提升数据处理效率,减少冗余代码。

此处评论已关闭