gpt4 book ai didi

php - 尝试从 Laravel 5.2 中的排队作业访问 session 数据

转载 作者:行者123 更新时间:2023-12-02 03:15:09 24 4
gpt4 key购买 nike

我正在构建一个网络应用程序,允许人们与老师预约时间。按照目前的情况,一旦将时间添加到用户购物车中,其他人就无法看到该时间可用或将其添加到他们的购物车中。

我正在使用 darryldecode's shopping cart只要 session 持续(2 小时),项目就会存储在其中。但是,我希望项目在添加 5 分钟后自动从中删除。为了实现这一点,我设置了一个延迟 5 分钟的排队作业。

我的问题是,该作业会更改时间以在 5 分钟后再次对其他用户可见,但不会将他们从购物车中删除,因为它似乎无法访问存储购物车数据的 session 。谁能建议我如何从排队的作业中访问存储在 session 中的购物车数据?谢谢。

这是工作的代码,除了 Cart::remove() 之外一切正常

namespace App\Jobs;

use App\Jobs\Job;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\TimeSlot;
use Cart;

class RemoveTimeSlotFromCart extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;

public $timeSlot;

/**
* Create a new job instance.
*
* @return void
*/
public function __construct(TimeSlot $timeSlot)
{
$this->timeSlot = $timeSlot;
}

/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$timeSlot = $this->timeSlot;
if ($timeSlot->booked == 0 && $timeSlot->in_basket == 1) {
$timeSlot->in_basket = 0;
$timeSlot->save();
Cart::remove($timeSlot->id);
}
}
}

最佳答案

Cron 作业在新 session 中运行。您的购物车库 (darryldecode/laravelshoppingcart) 是基于 session 的。如果它不是来自当前用户的浏览器启动的 session ,那么更改 session 数据将非常困难(也许不可能?取决于您的 session 驱动程序)。具体来说,这一行:

Cart::remove($timeSlot->id);

购物车模型无法知道要从哪个购物车中取出商品。从用户体验的角度来看——你会想要给用户一些反馈,告诉他们他们的时间段已经被取消了;因此,在每个页面绘制(或通过 js 异步)编写删除检查不应该是意外的工作。

在绘制的每个页面上,遍历访问者购物车中的每个项目。我不知道您是如何构建 cart::add(...) 来处理唯一的购物车商品 ID,因此这假设时间段 ID 与购物车商品 ID 匹配。

$removed = [];
foreach(Cart::getContent() as $item) {
$timeSlot = timeSlot::findOrFail($item->id);
if( $timeSlot->in_basket === 0 ) {
Cart::remove($timeSlot->id);
}
}
if(count($removed)) {
//inject a HTML/JS popup message like "your timeslot has been dropped because you're too slow
//or pass it along into the request
$request->session()->flash('slots-dropped', $removed);
}

这最好在 cartUpdate 中间件中处理,但也可以在 Controller 中完成,具体取决于您站点的复杂性。

[编辑]由于数据库结构,上述解决方案存在缺陷——用户A预订了一个时间段但没有在结账窗口内结账,时间段在用户A注意到之前几分钟返回到“不在购物车”状态;同时,在用户 B 返回到可用时隙池之后和用户 A 查看另一个页面之前(并且购物车使用适当的消息更新)之前,用户 B 看到了相同的时隙。此时时间段在 B 的购物车中。当页面刷新查看人员 A 的时间段是否在“任何”购物车中时 - 它说“是的,它在购物车中,因为 $timeslot->in_basket == 1 ”。人 A 继续结帐并获得时间段,即使它在人 B 的购物车中。

解决这个问题的方法非常简单——将 in_basket 的数据类型从 bool 值更改为字符串,并在每次将其添加到购物车时为其分配 session_id 的值。从我在购物车类中看到的,这可能是 app()->session->get('session')。你 var_dump(app()->session->all()) 看看这是否正确,然后再 promise 重构它。更新后的解决方案将如下所示:

$removed = [];
foreach(Cart::getContent() as $item) {
$timeSlot = timeSlot::findOrFail($item->id);
if( $timeSlot->in_basket !== app()->session->get('session') ) {
Cart::remove($timeSlot->id);
}
}
if(count($removed)) {
//inject a HTML/JS popup message like "your timeslot has been dropped because you're too slow
//or pass it along into the request
$request->session()->flash('slots-dropped', $removed);
}

关于php - 尝试从 Laravel 5.2 中的排队作业访问 session 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37417559/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com