【问题标题】:Laravel Event listener and caching not workingLaravel 事件监听器和缓存不起作用
【发布时间】:2018-04-28 19:12:46
【问题描述】:

我在 Laravel 上开发应用程序时遇到了一些困难。 我想使用Event and Listener to delete 并重建对象的缓存。

代码如下:

app\Events\CampaignEvent.php

namespace App\Events;

use Illuminate\Queue\SerializesModels;

class CampaignEvent extends Event
{
    use SerializesModels;
    public $user_id;
    public $cache_keys;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($user_id, $cache_keys)
    {
        $this->user_id = $user_id;
        $this->cache_keys = $cache_keys;
    }
}

app\Listenters\CampaignListener.php

<?php

namespace App\Listeners;

use App\Events\CampaignEvent;
use Cache;
use Log;
use App\BrandCampaign;

class CampaignListener
{

    /**
     * Handle the event.
     *
     * @param  CampaignEvent  $event
     * @return void
     */
    public function handle(CampaignEvent $event)
    {
        /**
         * Remove cache
         */
        if(is_array($event->cache_keys)){
            foreach($event->cache_keys as $index => $cache_key){
                \Cache::forget($cache_key);
                Log::debug("[CACHE] Deleted cache for: " . $cache_key);
            }
        } else {
            \Cache::forget($event->cache_keys);
            Log::debug("[CACHE] Deleted cache for: " . $event->cache_keys);
        }

        /**
         * Rebuild cache for BrandCampaigns
         */
        $campaigns = BrandCampaign::with(['influencers' => function($query){
            $query->with(['influencer' => function($query){
                $query->select('id','profile_picture');
            }])->latest();
        }])->where('user_id', $event->user_id )->latest()->get();

        $total_influencers = [];
        foreach($campaigns as $campaign){
            foreach ($campaign->influencers as $influencer) {
                if(!in_array($influencer->influencer_id, $total_influencers))
                    $total_influencers[] = $influencer->influencer_id;
            }
        }
        $total_influencers = count($total_influencers);

        $campaigns = collect($campaigns)->toArray();

        \Cache::forever('@suppliers_campaigns('.$event->user_id.')', $campaigns);
        \Cache::put('@suppliers_total_campaigns('.$event->user_id.')', $total_influencers, 10);

        Log::debug("[CACHE] Cache rebuilt successfully!");
        return $event;
    }
}

我想缓存一个数组"forever",但在我的活动控制器中,事件触发后,当我从缓存中拉出数组时,它返回null

谢谢!

【问题讨论】:

  • 你的缓存驱动是什么?您确定您的键 '@suppliers_campaigns('.$event-&gt;user_id.')' 和值 $campaigns 不为空且正确吗? Supplier_total_campaigns 的缓存是否有效?
  • 您能说明如何检索控制器中的数据吗?另一方面,为什么不将缓存导入为use Illuminate\Support\Facades\Cache;?也许您正在使用指向不同配置的不同缓存类。
  • 您是否在EventServiceProvider.php 文件中注册了您的事件和侦听器夫妇?
  • 很抱歉,如果这太明显了,但您是否在日志中验证了引用为已删除的键实际上与您期望的键匹配?您在此处提供的代码看起来不错,因此我倾向于认为您的问题在于提供它的内容。此外,还有一些离题的建议:“缓存”是别名,因此您不需要像 Adrian 建议的那样使用整个命名空间,您所拥有的一切都很好。您也不需要 SerializeModels 特征,因为该事件中没有模型。如果你对数组强制键入 $event->cache_keys,你可以取消 if/else 块并继续循环。
  • 这有点不相关,但您可能需要重新考虑一下您的设计。从理论上讲,监听器可以是异步的,并且可以由队列作业处理程序在应用程序的单独实例中执行,该处理程序甚至可能不在同一服务器上,从而使目标缓存超出范围。对于您的特定用例可能并非如此,但考虑到分离事件和侦听器的性质和目的,这感觉像是一种反模式。

标签: php laravel caching laravel-5 laravel-events


【解决方案1】:

适用于 Laravel 5(基于问题)和 Laravel 7(最新)。

use Illuminate\Support\Facades\Cache;

// Remove cache
Cache::forget('brandCampaigns');

// Rebuild cache for BrandCampaigns. Here, when the cache key doesn't exists, the function will be called and the returned value will be stored in the cache
$campaigns = Cache::rememberForever('brandCampaigns', function () {
    return BrandCampaign::with(['influencers' => function ($query) {
        $query->with(['influencer' => function ($query) {
            $query->select('id', 'profile_picture');
        }])->latest();
    }])->where('user_id', $event->user_id)->latest()->get();
});

【讨论】:

    猜你喜欢
    • 2023-01-13
    • 2020-05-08
    • 2015-06-06
    • 2020-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多