как обработать время приема запроса в laravel? - PullRequest
0 голосов
/ 14 апреля 2020

Я пытаюсь прочитать данные из файла Excel, а затем сохранить их в базе данных. но есть проблема. иногда файл имеет много данных почти 20000 записей. когда я пытаюсь обработать этот запрос с таким большим количеством данных, он обрабатывает в течение 2-3 минут и вводит около 13000 записей в базу данных, и после того, как этот запрос не был выполнен. вот что я делаю этот процесс выполняется в пяти функциях, каждая функция выполняет свою работу. Теперь я думаю, что должен сделать это по очереди, но я понятия не имею, как это будет работать, потому что я возвращаю некоторые вещи из каждой функции, которая не будет работать в очереди, и в моем контроллере также есть глобальный массив.

вот мой контроллер. Я думаю, вам не нужно читать все функции по одной, просто дайте мне представление, как я могу достичь своей цели

    //global array variable declaration for import delivery Zone
    protected $createdDeliveryZones;
    protected $updatedDeliveryZones;
    protected $errorDeliveryZones;
    /**
     * AddressController constructor.
     */
    public function __construct()
    {
        parent::__construct();
        $this->createdDeliveryZones = array();
        $this->updatedDeliveryZones = array();
        $this->errorDeliveryZones = array();
        $this->middleware('staff.permissions', ['only' => ['index', 'create', 'edit', 'delete']]);
    }
//delivery zone import function
    public function importDeliveryZone(Request $request)
    {

        if ($request->isMethod('get')) {
            return back();
        }
        $extension = $request->file('delivery_zone_file')->getClientOriginalExtension();
        if($extension != 'csv')
        {
            return back()->with('error','Please Choose CSV File');
        }  

        //getting spreadsheet data
        $path        = $request->file('delivery_zone_file')->getRealPath();
        $spreadsheet = IOFactory::load($path);
        $sheetData   = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);
        //these variable will decide from where locations are starting in spreadsheet
        $startAt = 2;
        $endAt     = count($sheetData);
        $validation = 1;

        //   loop will fetch row and pass it to function row by row
          foreach ($sheetData as $line_number => $delivery_zone) {
            //fileformatevalidation function will return 1 or 0 
            if($line_number == 1){
            //  $validation = $this->fileFormatValidation($delivery_zone,$line_number); 

             if($validation == 0){
                return back()->With('error','Please choose File with Correct Format');
            }
            }
            else 
            {

                    if ($line_number >= $startAt && $line_number <= $endAt && array_filter($delivery_zone)) {
                            $this->extractDeliveryZones($delivery_zone,$line_number);
                    }
                }
            }
            $errorDeliveryZones = $this->errorDeliveryZones;
            $updatedDeliveryZones = $this->updatedDeliveryZones;
            $createdDeliveryZones = $this->createdDeliveryZones;
            return view('web.pages.transports.delivery_zones.import_delivery_zone_validation',compact('errorDeliveryZones',$errorDeliveryZones,'updatedDeliveryZones',$updatedDeliveryZones,'createdDeliveryZones',$createdDeliveryZones));
    }

    public function fileFormatValidation($delivery_zone)
    {
        if($delivery_zone['A'] != 'id' || $delivery_zone['B'] != 'postcode' || $delivery_zone['C'] != 'suburb' || $delivery_zone['D'] != 'state' || $delivery_zone['E'] != 'country' || $delivery_zone['F'] != 'income_rate_zone' || $delivery_zone['G'] != 'expense_rate_zone' || $delivery_zone['H'] != 'delivery_run' || $delivery_zone['I'] != 'carrier' || $delivery_zone['J'] != 'customer')
        {

            return 0;
        }
        else 
        {
            return 1;
        }
    }

    public function extractDeliveryZones($delivery_zone,$line_number)
    {
        $data_validation = 1;

            //making array of location data
            $deliveryZoneArray = array('id' => $delivery_zone['A'],'postcode' => $delivery_zone['B'], 'suburb' => $delivery_zone['C'], 'address_zone' => $delivery_zone['D'],'country' => $delivery_zone['E']);
             // this function will validate data in excel sheet

            Customer::where('name',$delivery_zone['J'])->exists() ? $deliveryZoneArray['apply_to_customer'] = Customer::where('name',$delivery_zone['J'])->first()->id : $deliveryZoneArray['apply_to_customer'] = null;
            if(DeliveryRun::where('name',$delivery_zone['H'])->exists()) 
            {
            $deliveryZoneArray['delivery_run'] = DeliveryRun::where('name',$delivery_zone['H'])->first()->id;
            } 
             else 
            {
               $deliveryZoneArray['delivery_run'] = $delivery_zone['H'];
               $deliveryZoneArray['reason'] = "Delivery Run Dosn't Exist";
               array_push($this->errorDeliveryZones,$deliveryZoneArray);

               return 1;
             }

             $data_validation = $this->importFileDataValidation($deliveryZoneArray);

             if($data_validation == 1){

                $this->createDeliveryZoneFromExcel($deliveryZoneArray);
             }

    }

    public function createDeliveryZoneFromExcel($deliveryZoneArray)
    {
        if(empty($deliveryZoneArray['id']))
        {
            if(DeliveryZone::where('postcode',$deliveryZoneArray['postcode'])->where('suburb',$deliveryZoneArray['suburb'])->where('address_zone',$deliveryZoneArray['address_zone'])->exists())
            {
                $deliveryZoneArray['reason'] = "Duplicate postcode, suburb and state";
                array_push($this->errorDeliveryZones,$deliveryZoneArray);
            }

            else
            {
               DeliveryZone::create($deliveryZoneArray);
               array_push($this->createdDeliveryZones,$deliveryZoneArray);
            }
        }
        else
        {
            if(DeliveryZone::where('id',$deliveryZoneArray['id'])->exists())
            {
                $delivery_run = DeliveryZone::find($deliveryZoneArray['id'])->update($deliveryZoneArray);
                array_push($this->updatedDeliveryZones, $deliveryZoneArray);
            }
            else
            {
                $deliveryZoneArray['reason'] = "ID Doesn't Exist";
                array_push($this->errorDeliveryZones,$deliveryZoneArray);
            }
        }

    }

    public function importFileDataValidation($deliveryZoneArray)
    {
        $countries = array('Australia');
        if(empty($deliveryZoneArray['postcode']) || empty($deliveryZoneArray['suburb']) || empty($deliveryZoneArray['address_zone']))
        {
            $deliveryZoneArray['reason'] = 'Postcode, suburb or satate is Empty';
            array_push($this->errorDeliveryZones,$deliveryZoneArray);  
            return 0;
        }
       else if(!in_array($deliveryZoneArray['country'],$countries))
       {
        $deliveryZoneArray['reason'] = 'Country not Found';
        array_push($this->errorDeliveryZones,$deliveryZoneArray);  
        return 0;
       }
        else
        {
             return 1;
        }
    }

Ответы [ 2 ]

0 голосов
/ 17 апреля 2020

Я использовал set_time_limit(200) в каждой функции, связанной с этим процессом, и это была моя ошибка, я должен использовать ее только в первой функции. Теперь он работает нормально

0 голосов
/ 14 апреля 2020

Использование очередей или команд - хорошая практика для трудоемких задач.

Ответ может быть либо сохранен в базе данных и показан пользователю в следующей ссылке sh, либо показан с использованием такой службы, как Pusher, и отправить с помощью Broadcasting ответ из очереди на внешний интерфейс, когда задача выполнена.

...