Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/235.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如果用户将产品添加到购物车但从未签出,则检测会话将过期以恢复库存_Javascript_Php_Symfony - Fatal编程技术网

Javascript 如果用户将产品添加到购物车但从未签出,则检测会话将过期以恢复库存

Javascript 如果用户将产品添加到购物车但从未签出,则检测会话将过期以恢复库存,javascript,php,symfony,Javascript,Php,Symfony,我已经创建了一个带有产品表的在线商店。在每一行中都有一个名为stock的列,因此当用户向购物车中添加了stock=5的产品时,数据库中的库存设置为4 疑问:如果用户将产品添加到购物车中,但他/她从不去结账,他/她只是让浏览器打开很长时间..,如何恢复库存 由于我已将生存期cookie设置为1小时,如果用户已将某些产品添加到购物车并让浏览器处于非活动状态超过1小时,我希望恢复库存 我正在寻找PHP(或安全的Javascript客户端)解决方案 我使用symfony作为PHP框架。有许多不同的方法来

我已经创建了一个带有
产品
表的在线商店。在每一行中都有一个名为
stock
的列,因此当用户向购物车中添加了
stock=5
的产品时,数据库中的库存设置为
4

疑问:如果用户将产品添加到购物车中,但他/她从不去结账,他/她只是让浏览器打开很长时间..,如何恢复库存

由于我已将生存期cookie设置为1小时,如果用户已将某些产品添加到购物车并让浏览器处于非活动状态超过1小时,我希望恢复库存

我正在寻找PHP(或安全的Javascript客户端)解决方案


我使用symfony作为PHP框架。

有许多不同的方法来处理购物车的库存溢出,尽管我建议不要让用户会话或客户端实现控制库存。从数据的角度来看,您希望您的产品数据始终反映您在商店中的实际库存

一个相当简单的解决方案是使用设计如下的
购物车
表:

  • 用户ID
  • 产品ID
  • 数量
  • 添加日期/时间
当有人向购物车添加了一些东西时,您不需要更新
产品
表,而是在这个新的
购物车
表中插入一行。当他们与购物车进行其他交互时,您还可以刷新“添加的日期/时间”字段

每当您需要进行库存检查时,您都可以为项目获取
products.stock
的值,并减去
cart
表中当前的任何库存值,例如,使用类似以下的查询(使用MySQL作为示例):

SELECT products.stock-SUM(购物车数量)
来自产品
在products.id=cart.product\u id上左加入购物车
其中products.product_id=123
按产品分组。产品标识;
然后你会定期清理这张桌子,看看是否有过期产品。这可以通过cron任务完成,也可以更好地将其实现为一个Symfony事件,该事件可以在任何时候请求库存检查时发送

这就是Symfony解决方案的外观:

假设您的控制器中有一个股票价值检查,它访问一个执行类似于上述查询的服务方法:

$stock = $this->get('your_stock_service')->calculateStock($product);
相反,您可以先调度此事件:

use Example\Event\StockEvent;
use Example\Event\StockEvents;

// ...

$this->get('event_dispatcher')->dispatch(StockEvents::STOCK_CHECK, new StockEvent($product));

$stock = $this->get('your_stock_service')->calculateStock($product);
您的实际事件名称将在
Example\event\StockEvents.php
中定义(遵循Symfony约定):

单独设计一个事件监听器,比如说
StockEventListener

<?php

namespace Example\EventListener;

use Doctrine\ORM\EntityManager;
use Example\Event\StockEvent;

class StockEventListener
{
    /**
     * @var Doctrine\ORM\EntityManager
     */
    private $entityManager;

    /**
     * @param Doctrine\ORM\EntityManager $entityManager
     */
    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    /**
     * Remove any temporary stock from carts after one hour.
     *
     * @param StockEvent $stockEvent
     */
    public function clearTemporaryStock(StockEvent $stockEvent)
    {
        // use a cutoff of one hour
        $cutoff = new \DateTime();
        $cutoff->sub(new \DateInterval('1 hour'));

        $queryBuilder = $this->entityManager->createQueryBuilder();

        $queryBuilder
           ->delete('Example\Entity\Cart', 'c')
           ->where($queryBuilder->expr()->lt('c.date_added', ':cutoff'))
           ->andWhere($queryBuilder->expr()->eq('c.product', ':product'))
           ->setParameter('cutoff', $cutoff)
           ->setParameter('product', $stockEvent->getProduct())
           ->getQuery()
           ->execute();
    }
}
所有这些就绪后,每次检查产品库存时,控制器将首先调度事件,并执行上述侦听器,从表中清除任何过时的值

最后一点需要注意的是,对于一个复杂的商店来说,这可能仍然不是一个很好的解决方案,因为很大一部分购物车会掉下来,结果你会失去销售额。这实际上变成了一个用户体验的问题:你是否可以因为别人刚刚购买了一个产品而拒绝结账,或者你更愿意以这种方式锁定产品,并告诉用户“你有一个小时的时间用这个产品结账”或类似的事情


祝你好运

使用购物车处理库存溢出有很多不同的方法,不过我建议不要让用户会话或客户端实现控制库存。从数据的角度来看,您希望您的产品数据始终反映您在商店中的实际库存

一个相当简单的解决方案是使用设计如下的
购物车
表:

  • 用户ID
  • 产品ID
  • 数量
  • 添加日期/时间
当有人向购物车添加了一些东西时,您不需要更新
产品
表,而是在这个新的
购物车
表中插入一行。当他们与购物车进行其他交互时,您还可以刷新“添加的日期/时间”字段

每当您需要进行库存检查时,您都可以为项目获取
products.stock
的值,并减去
cart
表中当前的任何库存值,例如,使用类似以下的查询(使用MySQL作为示例):

SELECT products.stock-SUM(购物车数量)
来自产品
在products.id=cart.product\u id上左加入购物车
其中products.product_id=123
按产品分组。产品标识;
然后你会定期清理这张桌子,看看是否有过期产品。这可以通过cron任务完成,也可以更好地将其实现为一个Symfony事件,该事件可以在任何时候请求库存检查时发送

这就是Symfony解决方案的外观:

假设您的控制器中有一个股票价值检查,它访问一个执行类似于上述查询的服务方法:

$stock = $this->get('your_stock_service')->calculateStock($product);
相反,您可以先调度此事件:

use Example\Event\StockEvent;
use Example\Event\StockEvents;

// ...

$this->get('event_dispatcher')->dispatch(StockEvents::STOCK_CHECK, new StockEvent($product));

$stock = $this->get('your_stock_service')->calculateStock($product);
您的实际事件名称将在
Example\event\StockEvents.php
中定义(遵循Symfony约定):

单独设计一个事件监听器,比如说
StockEventListener

<?php

namespace Example\EventListener;

use Doctrine\ORM\EntityManager;
use Example\Event\StockEvent;

class StockEventListener
{
    /**
     * @var Doctrine\ORM\EntityManager
     */
    private $entityManager;

    /**
     * @param Doctrine\ORM\EntityManager $entityManager
     */
    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    /**
     * Remove any temporary stock from carts after one hour.
     *
     * @param StockEvent $stockEvent
     */
    public function clearTemporaryStock(StockEvent $stockEvent)
    {
        // use a cutoff of one hour
        $cutoff = new \DateTime();
        $cutoff->sub(new \DateInterval('1 hour'));

        $queryBuilder = $this->entityManager->createQueryBuilder();

        $queryBuilder
           ->delete('Example\Entity\Cart', 'c')
           ->where($queryBuilder->expr()->lt('c.date_added', ':cutoff'))
           ->andWhere($queryBuilder->expr()->eq('c.product', ':product'))
           ->setParameter('cutoff', $cutoff)
           ->setParameter('product', $stockEvent->getProduct())
           ->getQuery()
           ->execute();
    }
}
所有这些就绪后,每次检查产品库存时,控制器将首先调度事件,并执行上述侦听器,从表中清除任何过时的值

最后一点需要注意的是,对于一个复杂的商店来说,这可能仍然不是一个很好的解决方案,因为很大一部分购物车会掉下来,结果你会失去销售额。这真的成了一个用户体验的问题:你是否可以因为别人刚购买了一个产品而拒绝结账,或者你更愿意以这种方式锁定产品并告诉用户“你有一个小时的时间用这个产品结账”或者其他什么