猿问

PHP 服务器请求超时

 if($request->isPost()){
            $file =input('post.avatar');
            if(!$file){
                $this->error('请上传需要导入的表格!支持csv,xls,xlsx格式!');
            }
            $filePath = ROOT_PATH . DS . 'public' . DS . $file;
            if (!is_file($filePath)) {
                $this->error('上传的表格不存在,请核实');
            }
            $PHPReader = new \PHPExcel_Reader_Excel2007();
            if (!$PHPReader->canRead($filePath)) {
                    $PHPReader = new \PHPExcel_Reader_Excel5();
                if (!$PHPReader->canRead($filePath)) {
                        $PHPReader = new \PHPExcel_Reader_CSV();
                        $PHPReader->setInputEncoding('GBK');
                    if (!$PHPReader->canRead($filePath)) {
                        $this->error(__('Unknown data format'));
                    }
                }
            }
            $uptime = time();//用于判断插入记录的唯一时间戳
            $num = input('post.num');//获取商品数量
            $id = input('post.gid');//获取商品id
            $uid = $this->auth->id;//获取用户id
            $uname = $this->auth->username;
            $yu_money = $this->auth->money;//获取用户余额
            $level = $this->auth->level;//获取用户会员等级
            $store_id = input('post.store_id');//获取仓库编号
            $store_info = Db::name('send_store')->where('id',$store_id)->find();//获取仓库记录
            $is_multiple = $store_info['is_multiple'];
            if($is_multiple==0){
                $num = 1;
            }
            $express_id = $store_info['express_id'];//快递编号
            $express_price = get_price($level,$express_id);//获取快递价格
            $goods_info = Db::name('goods')->where('id',$id)->find();
            $weight = $goods_info['weight'];
            $goods_price = $goods_info['price'];//获取商品单价
            $total_fee = $num*$goods_price+$express_price;//计算总价
            $send_store = $store_info['send_code'];//获取发货仓编号
            $store_name = $store_info['store_name'];//获取发货仓name
            $father_code = trim(get_father_code($id,$express_id));//获取主站商品编号
            $PHPExcel = $PHPReader->load($filePath); //加载文件
            $currentSheet = $PHPExcel->getSheet(0);  //读取文件中的第一个工作表
            $allRow = $currentSheet->getHighestRow(); //取得一共有多少行 
            $pttype = $currentSheet->getCell("A1")->getValue();//是什么平台表格
            $leijia = '';
            $continue_num = 0;
            for($i=2;$i<=$allRow;$i++){
                if($yu_money < $total_fee){
                    $upinfo=Db::name('upinfo');
                    $info['user_id'] = $uid;
                    $info['exnum'] = $allRow-1;//要插入数据库的总记录数
                    $info['oknum'] = $i-2;//成功插入的数量
                    $info['tableid'] = $uptime;//此次任务的id
                    $info['expressid'] = $express_id;
                    $info['vars'] = '余额不足';
                    $upinfo->insert($info);
                    $this->error("余额不足,成功发布了".($i-2)."条记录",url('Express/tblist'));
                }
                if($pttype=='订单编号'){//淘宝
                    $out_order_no = $currentSheet->getCell("A".$i)->getValue();//订单号
                    $address_ren =  $currentSheet->getCell("O".$i)->getValue();//收件人
                    $address_array = preg_replace('/(,)|(,)/','',$currentSheet->getCell("P".$i)->getValue());//收货地址
                    $address_hao = preg_replace('/\W/','',$currentSheet->getCell("S".$i)->getValue());//号码
                }else if($pttype=='商品'){//拼多多
                    $out_order_no =  $currentSheet->getCell("B".$i)->getValue();
                    $address_ren =  $currentSheet->getCell("O".$i)->getValue();//收件人
                    $address_hao = preg_replace('/\W/','',$currentSheet->getCell("P".$i)->getValue());//收件号码 
                    $add_s =  $currentSheet->getCell("Q".$i)->getValue();//省
                    $add_c =  $currentSheet->getCell("R".$i)->getValue();//市
                    $add_a =  $currentSheet->getCell("S".$i)->getValue();//区
                    $add_d =  $currentSheet->getCell("T".$i)->getValue();//地址
                    $address_array = $add_s.' '.$add_c.' '.$add_a.' '.$add_d;//收件地址
                }else if($pttype=='订单号'){//模板
                    $out_order_no =  $currentSheet->getCell("A".$i)->getValue(); 
                    $address_array = preg_replace('/(,)|(,)/','',$currentSheet->getCell("B".$i)->getValue());//收件地址
                    $address_ren =  $currentSheet->getCell("C".$i)->getValue();//收件人
                    $address_hao = preg_replace('/\W/','',$currentSheet->getCell("D".$i)->getValue());//收件号码
                }else{
                    $this->error('提交的表格格式错误,请按照导入说明操作!');
                }
                $out_order_no = preg_replace('# #','',$out_order_no);//订单号
                $address_hao = preg_replace('# #','',$address_hao);//收件人手机号
                $address_ren = preg_replace('# #','',$address_ren);//收件人
                //验证订单号是否为空
                if(empty($out_order_no)){
                    $leijia = $leijia.'第'.$i.'行订单号为空,';
                    continue;
                }
                $isorder = Db::name('express')->where('out_order_no',trim($out_order_no))->find();
                //验证订单是否重复提交
                if ($isorder)
                {   
                    $leijia = $leijia.'第'.$i.'行地址订单号'.$isorder['out_order_no'].'重复,';
                    continue;
                }
                //验证收件人手机号是否为空
                if(empty($address_hao)){
                    $leijia = $leijia.'第'.$i.'行收件人手机号为空,';
                    continue;
                }
                //验证收货地址是否为空
                if(empty(preg_replace('# #','',$address_array))){
                    $leijia = $leijia.'第'.($i).'行收件地址为空,';
                    continue;
                }
                //验证收件人是否为空
                if(empty($address_ren)){
                    $leijia = $leijia.'第'.$i.'行收件人为空,';
                    continue;
                }
                //验证收货地址是否合理
                $addrlist = explode(" ",$address_array);
                $addrlist = array_filter($addrlist);
                $addrlist = array_values($addrlist);
                if(count($addrlist)<4)
                {
                    $leijia = $leijia.'第'.$i.'行收货地址不合理,';
                    continue;
                }
                // ini_set("display_errors","On");
                // error_reporting(E_ALL);
                switch ($express_id) {
                    case 1:
                        //接口请求参数
                        $post_info = [
                            'accessToken'=>config('get_yto_config.token'),
                            'storehouseCode'=>$send_store,'goodsCode'=>$father_code,
                            'receiver'=>$address_ren,'receiverPhone'=>$address_hao,
                            'receiverProvinceName'=>$addrlist[0],'receiverCityName'=>$addrlist[1],
                            'receiverAreaName'=>$addrlist[2],'receiverAddress'=>$addrlist[3],
                            'thirdOrderNo'=>$out_order_no,'goodsNum'=>$num,'shipperName'=>$uname
                        ];
                        //请求接口
                        $json = sendRequest('',$post_info,'POST');
                        $return = json_decode($json,1);
                        $code = $return['code'];
                        if($code==0){
                            $return_data = $return['data'];
                            $taskid = $return_data['recordId'];
                            //处理成功时的业务逻辑
                            $result = [];
                            $result[$i] = [
                                'user_id'=>$uid,
                                'express_no'=>'0',
                                'out_order_no'=>$out_order_no,
                                'expressid'=>$express_id,
                                'weight'=>$weight,
                                'price'=>$total_fee,
                                'num'=>$num,
                                'goods'=>$id,
                                'addressee'=>$address_ren,
                                'a_mphone'=>$address_hao,
                                'all_address'=>$address_array,
                                'taskid'=>$taskid,
                                'sender'=>$store_name,
                                'tableid'  => $uptime,
                                'from'  => 1 
                            ];
                            //更新用户信息
                            $retu = model('express')->saveAll($result);
                            $yu_money = $yu_money-$total_fee;
                            \app\common\model\User::score($score=0,'-'.$total_fee,$uid,'购买礼品,编号'.$retu[$i]['id']);
                            $continue_num = $continue_num+1;
                        }else{
                            $this->error($return['msg']);
                        }
                        break;
                    case 4:
                        //接口请求数据
                        $orderParams = [];
                        $orderParams[0] = [
                            'apiOrderId'=>$out_order_no,//订单唯一标识
                            'buyerName' =>$address_ren,//收件人
                            'buyerMobile'=>$address_hao,//收件人手机号
                            'buyerAddr'=>$address_array,//收件地址
                            'storeType'=>$send_store,//发货仓编号
                            'kuaidiName'=>get_express_name($express_id)
                        ];
                        $orderParams = json_encode($orderParams);
                        $post_info = [
                            'partnerId'   =>'',//合作商ID
                            'itemId'      =>$father_code,//韵达礼品对应商品编号
                            'orderParams' =>$orderParams,//订单信息
                            'validation'   =>md5($father_code.$orderParams.''.'')
                        ];
                        $json = sendRequest('',$post_info,'post');
                        $return  = json_decode($json,1);
                        if($return['result']===1){
                            $return_info = $return['orders'][0];
                            $out_order_no = $return_info['apiOrderId'];//订单唯一标识
                            $express_no = $return_info['expressNo'];//快递面单号
                            //处理成功时的业务逻辑
                            $result = [];
                            $result[$i] = [
                                'user_id'=>$uid,
                                'express_no'=>$express_no,
                                'out_order_no'=>$out_order_no,
                                'expressid'=>$express_id,
                                'weight'=>$weight,
                                'price'=>$total_fee,
                                'num'=>$num,
                                'goods'=>$id,
                                'addressee'=>$address_ren,
                                'a_mphone'=>$address_hao,
                                'all_address'=>$address_array,
                                'sender'=>$store_name,
                                'tableid'  => $uptime,
                                'from'  => 1 
                            ];
                            //更新用户信息
                            $retu = model('express')->saveAll($result);
                            $yu_money = $yu_money-$total_fee;
                            \app\common\model\User::score($score=0,'-'.$total_fee,$uid,'购买礼品,编号'.$retu[$i]['id']);
                            $continue_num = $continue_num+1;
                        }else{
                            $this->error($return['message']);
                        }
                        break;
                    default:
                        # code...
                        break;
                }
            }
            $upinfo=Db::name('upinfo');
            $info['user_id'] = $uid;
            $info['exnum'] = $allRow-1;//要插入数据库的总记录数
            $info['oknum'] = $continue_num;//成功插入的数量
            $info['tableid'] = $uptime;//此次任务的id
            $info['expressid'] = $express_id;
            $info['vars'] = $leijia=='' ?'全部导入成功':$leijia;
            $upinfo->insert($info);
            $this->success("发布成功".($continue_num)."条",url('Express/exlist'));
        }

上面是我处理业务逻辑的代码 对方接口一次最多只接受5条数据
我读取表格后 通过for循环 一条一条读取表格的记录 在循环体内一次一次请求外部接口 今天有一个客户上传的表格太大 导致整个循环体循环时间太长 服务器超时 请问这种问题我改怎么解决 拜托各位大佬帮忙给我个建议

DIEA
浏览 829回答 3
3回答

FFIVE

借助消息队列实现异步处理耗时任务

GCT1015

$allRow 是最大读取条数嘛?可以试试把获取的数组转成collect()然后调用chunk()分片处理库操作尽可能提出去一次处理

子衿沉夜

用消息队列,异步化,同时不用这个excel包,用csv文本文件
随时随地看视频慕课网APP
我要回答