Laravel cache :: remember以数组的形式重现对象 [英] Laravel cache::remember is returing object as an array

查看:2177
本文介绍了Laravel cache :: remember以数组的形式重现对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Laravel Cache::remember返回一个LengthAwarePaginator对象作为数组.

Laravel Cache::remember is returning a LengthAwarePaginator object as an array.

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;
}

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

If I dd($query) before returning from Cache closure, it's returning the following object, that accepts $value->links() to display pagination.

但是每当缓存将$query存储到$values时,它都会以数组的形式返回值:

But whenever the Cache is storing $query into $values it's returning values as an array:

我尝试注释掉反序列化块:

I tried commenting out the unserialize-block:

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

并确认,这不是原因.

我也尝试过,但是失败了:

I also tried, but failed:

$values = collect($values);

通过多次检查和交叉检查,我确认,问题是Cache::remember .

With multiple check and cross-check I am confirming that, the issue is the Cache::remember.

如何强制Cache::remember返回原样?这样我就可以让 $object->links() 为我.

How can I force the Cache::remember return things as it is? So that I can let $object->links() work for me.

可以在此处找到代码.

推荐答案

问题是,缓存用于存储数据,而不是实例.因此,有两种方法可以做到这一点:

Issue is, Cache is made to store data, not the instance. So there are two ways to do this:

  1. 缓存时,每页缓存信息
  2. 在获取时获取所有数据,但进行自己的分页
  1. When caching, cache information per page, or
  2. Get all the data while fetching, but make your own pagination

解决方案1:

我们去了第二次.但是,如果您需要第一个解决方案,这是代码,我得到了来自Laracasts ,由chrisml提供:

Solution 1:

We went for the second. But in case you need to go for the first solution, here's the code, I got from Laracasts, provided by chrisml:

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

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

On the above code, the cache key is changing on every page, so the cache is storing per page.

但是对于我来说,我们认为应该第二次,对于我们而言,这对我们来说是明智的.因此,我们必须进行自己的分页.幸运的是,psampaz在他们的博客上为我们奠定了基础:

But for my case, we thought we should go for the second, and that would be wise for us, in our case. So, we've to make our own pagination. My luck that, psampaz did the base for us on their blog:

  • Custom data pagination with Laravel 5 — by psampaz

因此,我们不是先使用->paginate(),而是先获取所有数据,然后像以前一样缓存它们.

So, instead of using ->paginate() we're fetching all the data first, and caching them as previous.

$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的代码进行了一些修复:

But before returning the $values, we're making our own pagination. We made some fixes to psampaz's code:

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()进行分页,这太棒了! :)

And finally we can easily use the $object->links() for pagination, and it's awesome! :)

这篇关于Laravel cache :: remember以数组的形式重现对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆