【问题标题】:How can I paginate an array of objects in Laravel?如何在 Laravel 中对一组对象进行分页?
【发布时间】:2014-11-21 15:37:03
【问题描述】:

我正在使用 Laravel 4.2 构建一个应用程序。我有units 的模型和users 的另一个模型和数据透视表user_units。此应用程序中的每个用户都可以选择一个单元并将其添加到他最喜欢的列表中,然后他可以将该单元与他的信息一起作为广告发布。

我要选择所有用户发布的所有单元

user_units(数据透视表)具有以下列:

id   
user_id 
unit_id 
publish      
adtype       
addinfo          
created_at  
updated_at

在模型上使用关系方法

public function users() {
    return $this->belongsToMany('User', 'user_units')
                ->withPivot('id','publish', 'adtype', 'addinfo');
}

public function units() {
    return $this->belongsToMany('Unit', 'user_units')
                ->withPivot('id','publish', 'adtype', 'addinfo');
}

我的查询选择所有用户发布的所有单位

// Get all published units by users for sale. 
    $users = User::all();
    $publishedSaleUnits = [];
    foreach($users as $user){
        $userUnits = $user->units()->orderBy('adtype', 'desc')->get();
        if(count($userUnits)){
            foreach($userUnits as $unit){
                if($unit->pivot->publish == 1 && $unit->unit_purpose_id == 1){
                    if( $unit->pivot->adtype ){
                        //push all featured ads onto the beginning of array
                        array_unshift($publishedSaleUnits, $unit);
                    }else{
                        //push all normal ads onto the end of array
                        array_push($publishedSaleUnits, $unit);
                    }
                }
            }
        }
    }

现在我得到了结果,但我不能对结果使用分页,因为它是一个对象数组。

那么有没有更好的解决方案来让用户通过分页获取所有已发布的单元?

【问题讨论】:

    标签: laravel-4 pagination pivot-table


    【解决方案1】:

    根据这篇文章 https://www.itsolutionstuff.com/post/how-to-create-pagination-from-array-in-laravelexample.html

    您可以通过创建自定义方法并使用 LengthAwarePaginator 对数组进行分页

    namespace App\Http\Controllers;
      
    use Illuminate\Http\Request;
    use Illuminate\Pagination\Paginator;
    use Illuminate\Support\Collection;
    use Illuminate\Pagination\LengthAwarePaginator;
      
    class PaginationController extends Controller
    {
        public function index()
        {
            $myArray = [
                ['id'=>1, 'title'=>'Laravel CRUD'],
                ['id'=>2, 'title'=>'Laravel Ajax CRUD'],
                ['id'=>3, 'title'=>'Laravel CORS Middleware'],
            ];
      
            $data = $this->paginate($myArray);
            return view('paginate', compact('data'));
        }
       
        public function paginate($items, $perPage = 5, $page = null, $options = [])
        {
            $page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
            $items = $items instanceof Collection ? $items : Collection::make($items);
            return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, $options);
        }
    }
    

    【讨论】:

    • 完美答案。
    • 同样的例子不适用于 laravel 8 的 API
    • 使用 laravel 8 对我的代码进行了测试和调整。
    【解决方案2】:

    您查询数据的方法效率极低。在一个查询中获取您的数据。嵌套遍历不仅难以阅读,而且是性能杀手。

    到分页问题:

    Laravel 提供了一个 Pagignator 工厂。有了它,您将能够使用自己的数据构建自己的 Paginator。

    就这么简单

    $units = Paginator::make($unit, count($unit), 10);
    

    如果您使用的是 Facade。否则 Illuminate\Pagination\Factory 就是你要找的类。

    【讨论】:

    • $units = Paginator::make($units, count($units), 10);我在创建 $units->links() 之前尝试了这种方法,但每个页面都包含来自 $units 数组的所有结果
    • 我使用 paginator::make 对 $publishedSaleUnits 数组中的记录进行分页。但鉴于我正在获取分页链接,但所有链接中都有所有记录。如何将其限制为每页项目。
    【解决方案3】:

    你可以用你自己的数组试试我的代码,

    $page = isset($request->page) ? $request->page : 1; // Get the page=1 from the url
    $perPage = $pagination_num; // Number of items per page
    $offset = ($page * $perPage) - $perPage;
    
    $entries =  new LengthAwarePaginator(
        array_slice($contact_list, $offset, $perPage, true),
        count($contact_list), // Total items
        $perPage, // Items per page
        $page, // Current page
        ['path' => $request->url(), 'query' => $request->query()] // We 
           need this so we can keep all old query parameters from the url
    );
    

    【讨论】:

      【解决方案4】:

      我得到了一个更好的对数组结果进行分页的解决方案,我找到了答案here

      Paginator::make 函数我们只需要传递所需的值而不是所有值。因为paginator::make 函数只是显示发送给它的数据。要将正确的偏移分页数据发送到paginator::make,应遵循以下方法

          $perPage = 5;   
          $page = Input::get('page', 1);
          if ($page > count($publishedSaleUnits) or $page < 1) { $page = 1; }
          $offset = ($page * $perPage) - $perPage;
          $perPageUnits = array_slice($publishedSaleUnits,$offset,$perPage);
          $pagination = Paginator::make($perPageUnits, count($publishedSaleUnits), $perPage);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-02
        • 1970-01-01
        • 2017-09-01
        • 1970-01-01
        • 2022-01-08
        相关资源
        最近更新 更多