Laravel cache :: remember是将对象作为数组进行处理

时间:2017-05-17 14:45:54

标签: caching laravel-5.2

Laravel Cache::remember正在返回一个LengthAwarePaginator对象作为数组。

function getNotifications( $userID ) {
    $values = Cache::remember('cache-key', 10, function() {

        $query = DB::table( 'user_notifications' )
                ->leftJoin( 'notifications', 'user_notifications.notification_id', '=', 'notifications.id' )
                ->where( 'user_notifications.user_id', $userID )
                ->select( 'notifications.*' )
                ->orderBy('created_at', 'DESC')
                ->paginate(5);

        return $query;

    });

    return $values;
}

如果我在从Cache闭包返回之前dd($query),它将返回以下对象,该对象接受$value->links()以显示分页。 LengthAwarePaginator

但是当缓存将$query存储到$values时,它会将值作为数组返回: Array of values

我试着评论unserialize-block:

/*foreach( $values as $key => $value ) :
    $values[$key]->meta = self::maybeUnserialize($value->meta);
endforeach;*/

并确认,这不是原因。

我也试过了,但失败了:

$values = collect($values);

通过多次检查和反复核对,我确认,问题是Cache::remember

如何强制Cache::remember返回原样?所以我可以让$object->links()为我工作。

可以找到实际代码here

1 个答案:

答案 0 :(得分:0)

问题是,Cache用于存储数据,而不是实例。所以有两种方法可以做到这一点:

  1. 缓存时,缓存每页的信息
  2. 获取时获取所有数据,但制作自己的分页
  3. 解决方案1:

    我们去了第二个。但是如果你需要第一个解决方案,这里是代码,我得到from Laracasts,由chrisml提供:

    $statuses = Cache::remember('statuses_' . $id . '_page_' . $page, 3, function() use ($event, $sort) {
        return $event->statuses()
            ->with('comments')
            ->latest()
            ->paginate(10);
    });
    

    在上面的代码中,缓存键在每个页面上都在变化,因此缓存每页存储一次。

    解决方案2:

    但对于我的情况,我们认为我们应该选择第二种,在我们的案例中,这对我们来说是明智的。所以,我们要做自己的分页。我的运气,psampaz在他们的博客上为我们做了基础:

    因此,我们不是先使用->paginate(),而是首先获取所有数据,然后将其缓存为之前的数据。

    $values = Cache::remember('cache-key', 10, function() {
    
        $query = DB::table( 'user_notifications' )
                ->leftJoin( 'notifications', 'user_notifications.notification_id', '=', 'notifications.id' )
                ->where( 'user_notifications.user_id', $userID )
                ->select( 'notifications.*' )
                ->orderBy('created_at', 'DESC')
                ->get(); // <----------- here
    
        return $query;
    
    });
    

    但在返回$values之前,我们正在制作自己的分页。我们修改了psampaz的代码:

    use Illuminate\Support\Collection;
    use Illuminate\Pagination\LengthAwarePaginator;
    
    function getNotifications( $userID ) {
    
        // Collapsed the cached values here :)
        $values = Cache::remember('cache-key', 10, function() {...});
    
        // Get current page form url e.g. &page=6.
        $currentPage = LengthAwarePaginator::resolveCurrentPage();
    
        // Get current path.
        $currentPath = LengthAwarePaginator::resolveCurrentPath();
    
        // Create a new Laravel collection from the array data.
        $collection = new Collection($values);
    
        // Define how many items we want to be visible in each page.
        $perPage = 5;
    
        // Slice the collection to get the items to display in current page.
        $results = $collection->slice(($currentPage - 1) * $perPage, $perPage)->all();
    
        // Create our paginator and pass it to the view.
        $values = new LengthAwarePaginator($results, count($collection), $perPage, $currentPage, ['path' => $currentPath]);
    
        return $values;
    }
    

    最后我们可以轻松地使用$object->links()进行分页,这太棒了! :)