>  기사  >  백엔드 개발  >  PHP와 redis는 쇼핑몰 플래시 세일 기능 코드 공유를 실현합니다.

PHP와 redis는 쇼핑몰 플래시 세일 기능 코드 공유를 실현합니다.

小云云
小云云원래의
2018-02-09 09:18:344710검색

이 글은 쇼핑몰의 플래시 세일 기능을 구현하기 위해 주로 php+redis를 소개합니다. 관심 있는 친구들이 참고하면 도움이 될 것입니다.

1. Redis를 설치하고 자신의 PHP 버전에 따라 해당 Redis 확장을 설치합니다(이 단계를 간략하게 설명).

1.1 여기에서 표시된 대로 php_igbinary.dll, php_redis.dll 확장을 설치해야 합니다. 그림에서:

1.2.php.ini 파일에는 두 개의 새로운 확장자가 있습니다: Extension=php_igbinary.dll;extension=php_redis.dll

ok 여기서는 Redis 환경을 구축하기 위한 첫 번째 단계가 완료되었습니다. phpinfo

2. Redis는 실제로 프로젝트

2.1에서 사용됩니다. 첫 번째 단계는 Redis 설치를 위한 기본 포트는 6379입니다:


<?php
/* 数据库配置 */
return array(
  &#39;DATA_CACHE_PREFIX&#39; => &#39;Redis_&#39;,//缓存前缀
  &#39;DATA_CACHE_TYPE&#39;=>&#39;Redis&#39;,//默认动态缓存为Redis
  &#39;DATA_CACHE_TIMEOUT&#39; => false,
  &#39;REDIS_RW_SEPARATE&#39; => true, //Redis读写分离 true 开启
  &#39;REDIS_HOST&#39;=>&#39;127.0.0.1&#39;, //redis服务器ip,多台用逗号隔开;读写分离开启时,第一台负责写,其它[随机]负责读;
  &#39;REDIS_PORT&#39;=>&#39;6379&#39;,//端口号
  &#39;REDIS_TIMEOUT&#39;=>&#39;300&#39;,//超时时间
  &#39;REDIS_PERSISTENT&#39;=>false,//是否长连接 false=短连接
  &#39;REDIS_AUTH&#39;=>&#39;&#39;,//AUTH认证密码 
);
?>

2.2. 실제 기능에 사용되는 것 :


/**
    * redis连接
    * @access private
    * @return resource
    * @author bieanju
    */
  private function connectRedis(){
    $redis=new \Redis();
    $redis->connect(C("REDIS_HOST"),C("REDIS_PORT"));    
    return $redis;
  }

2.3 플래시 세일의 핵심 문제는 대량 동시 구매의 경우 재고를 초과하지 않는다는 점입니다. 이것이 처리의 핵심이므로 아이디어는 다음과 같습니다. 첫 번째 단계로 플래시 세일 카테고리에서 기본 데이터 생성을 수행하는 것입니다:


//现在初始化里面定义后边要使用的redis参数
public function _initialize(){
    parent::_initialize();
    $goods_id = I("goods_id",&#39;0&#39;,&#39;intval&#39;);   
    if($goods_id){
      $this->goods_id = $goods_id;
      $this->user_queue_key = "goods_".$goods_id."_user";//当前商品队列的用户情况
      $this->goods_number_key = "goods".$goods_id;//当前商品的库存队列
    }
    $this->user_id = $this->user_id ? $this->user_id : $_SESSION[&#39;uid&#39;];   
  }

2.4. 두 번째 단계는 제품 세부 정보 페이지에 들어가기 전에 사용자가 먼저 현재 제품 재고를 대기열에 추가하고 다음과 같이 redis에 저장합니다:


/**
  * 访问产品前先将当前产品库存队列
  * @access public
  * @author bieanju
  */
  public function _before_detail(){
    $where[&#39;goods_id&#39;] = $this->goods_id;
    $where[&#39;start_time&#39;] = array("lt",time());
    $where[&#39;end_time&#39;] = array("gt",time());
    $goods = M("goods")->where($where)->field(&#39;goods_num,start_time,end_time&#39;)->find();
    !$goods && $this->error("当前秒杀已结束!");
    if($goods[&#39;goods_num&#39;] > $goods[&#39;order_num&#39;]){
      $redis = $this->connectRedis();
      $getUserRedis = $redis->hGetAll("{$this->user_queue_key}");
      $gnRedis = $redis->llen("{$this->goods_number_key}");
      /* 如果没有会员进来队列库存 */
      if(!count($getUserRedis) && !$gnRedis){      
        for ($i = 0; $i < $goods[&#39;goods_num&#39;]; $i ++) {
          $redis->lpush("{$this->goods_number_key}", 1);
        }
      }
      $resetRedis = $redis->llen("{$this->goods_number_key}");
      if(!$resetRedis){
        $this->error("系统繁忙,请稍后抢购!");
      }
    }else{
      $this->error("当前产品已经秒杀完!");
    }
     
  }

다음으로 할 일은 사용자가 구매 버튼을 클릭할 때 조건을 충족하는 데이터를 ajax를 사용하여 비동기적으로 처리하는 것입니다. 구매 대기열에 들어갑니다(현재 사용자가 아닌 경우). 현재 제품 사용자의 대기열에 대기열을 입력하고 인벤토리 대기열을 팝하고, 그렇다면 버리십시오.):


/**
   * 抢购商品前处理当前会员是否进入队列
   * @access public
   * @author bieanju
   */
  public function goods_number_queue(){
    !$this->user_id && $this->ajaxReturn(array("status" => "-1","msg" => "请先登录"));
    $model = M("flash_sale");
    $where[&#39;goods_id&#39;] = $this->goods_id;
    $goods_info = $model->where($where)->find();
    !$goods_info && $this->error("对不起当前商品不存在或已下架!"); 
    /* redis 队列 */ 
    $redis = $this->connectRedis();
    /* 进入队列 */
    $goods_number_key = $redis->llen("{$this->goods_number_key}");
    if (!$redis->hGet("{$this->user_queue_key}", $this->user_id)) {
      $goods_number_key = $redis->lpop("{$this->goods_number_key}");
    }
     
    if($goods_number_key){
      // 判断用户是否已在队列
      if (!$redis->hGet("{$this->user_queue_key}", $this->user_id)) {
        // 插入抢购用户信息
        $userinfo = array(
          "user_id" => $this->user_id,
          "create_time" => time()
        );        
        $redis->hSet("{$this->user_queue_key}", $this->user_id, serialize($userinfo));
        $this->ajaxReturn(array("status" => "1"));
      }else{
        $modelCart = M("cart");
        $condition[&#39;user_id&#39;] = $this->user_id;
        $condition[&#39;goods_id&#39;] = $this->goods_id;
        $condition[&#39;prom_type&#39;] = 1;
    $cartlist = $modelCart->where($condition)->count();
        if($cartlist > 0){
          $this->ajaxReturn(array("status" => "2"));
        }else{
         
          $this->ajaxReturn(array("status" => "1"));
         
        }
         
      }
       
    }else{
      $this->ajaxReturn(array("status" => "-1","msg" => "系统繁忙,请重试!"));
    }
  }

지정된 대기열 값을 삭제하는 디버깅 기능 첨부:


public function clearRedis(){
     set_time_limit(0);
     $redis = $this->connectRedis();
     //$Rd = $redis->del("{$this->user_queue_key}");
     $Rd = $redis->hDel("goods49",&#39;用户id&#39;&#39;);
     $a = $redis->hGet("goods_49_user", &#39;用户id&#39;);
     if(!$a){
       dump($a);
     }
     
     if($Rd == 0){
       exit("Redis队列已释放!");      
     }
   }

여기까지 오면 플래시 세일의 핵심은 기본적으로 끝났습니다. 장바구니 처리, 주문 처리 등 세부 사항은 아직 스스로 개선해야 합니다. 이제 프로그램을 실행하고 Apache 자체를 사용해 보겠습니다. ab 다음과 같이 간단한 시뮬레이션 동시성 테스트를 수행할 수 있습니다.

실행하면 redis가 전혀 응답하지 않습니다. 이때 redis 서비스를 활성화하는 중요한 단계가 누락되었습니다. 또는 Redis 서비스 관리 도구에 따라 redisbin_x64를 선택하세요. redis-server.exe를 클릭하세요. 이제 아래와 같이 모든 것이 완료되었습니다.

관련 권장 사항:

웹에서 자동 플래시 판매를 실현하는 JS 스크립트 페이지

플래시 세일을 실현하는 Yii 프레임워크 redis+php 효과 분석 예시

재고 과매도 방지를 위한 몰 플래시 세일

위 내용은 PHP와 redis는 쇼핑몰 플래시 세일 기능 코드 공유를 실현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.