Как отправить ответ пользователю перед отправкой почты в php - PullRequest
0 голосов
/ 02 июля 2019

Я занимаюсь разработкой проекта, и в нем два процесса.

  1. Отправка почты.
  2. Отправка ответа пользователю.

Мне нужно сделать все это, но это занимает много времени.Так что теперь я думаю использовать многопоточность.Может кто-нибудь помочь, как добиться этого в php?

Мне просто нужно отправить ответ как можно скорее.Вот мой код: я делаю функцию для отправки почты, и после успешной полной доставки почты я отправляю ответ пользователю, используя кодирование JSON.

/ функция почты /

public function emailSent($booking_id, $mailHeading, $smallHeading, $subject, $smallHeadingcustomer ,$status, $senttoestimator = true, $senttocustomer = true, $mailSent = false){
        if(!empty($booking_id)){
             $bookingData = $this->Cnc_model->getData('bookings', array('*'), array('id'=>$booking_id));

            if(!empty($bookingData)){
                if(!empty($bookingData[0]['estimator_id']) && $bookingData[0]['estimator_id'] != 0){
                    $name = $this->Cnc_model->getData('users',array('username', 'email'), array('user_id'=> $bookingData[0]['estimator_id']));   
                    $estimator_name = $name[0]['username'];
                    $estimator_mail = $name[0]['email']; 
                    }
                if($bookingData[0]['customer_id'] != 0){
                    $cname = $this->Cnc_model->getData('customers',array('name', 'office_contact_email'), array('id'=> $bookingData[0]['customer_id']));   
                    $customer_name = $cname[0]['name'];
                    $customer_mail = $cname[0]['office_contact_email'];
                }

                $fromEmail = FROM;
                $emailData = array(
                        "customeName" => $customer_name,
                        "estimator_name"=>$estimator_name,
                        "booking_title" => !empty($bookingData[0]['booking_title']) ? $bookingData[0]['booking_title']: 'No Title',
                        "booking_date" => date("d-m-Y",strtotime($bookingData[0]['booking_date'])),
                        "start_time" => date("h:i a",strtotime($bookingData[0]['start_time'])),
                        "end_time" => date("h:i a",strtotime($bookingData[0]['end_time'])),
                        "address" =>isset($bookingData[0]['location']) ? $bookingData[0]['location']: '',
                        "notes" => isset($bookingData[0]['notes']) && !empty($bookingData[0]['notes'])?$bookingData['notes']:'No Notes For this booking',
                        "status" => isset($status) && !empty($status)? $status:'',
                        "bookingId" => $bookingData[0]['id'],
                        'mainHeading'=> isset($mailHeading) && !empty($mailHeading)?$mailHeading:'',
                        'smallHeading'=>isset($smallHeading) && !empty($smallHeading)?$smallHeading:'',
                        'smallHeadingcustomer' => isset($smallHeadingcustomer) && !empty($smallHeadingcustomer)?$smallHeadingcustomer: '',
                    );
                if($bookingData[0]['status']!=3 && $bookingData[0]['status']!=0 || $mailSent == true ){
                  if(!empty($emailData) && $senttocustomer){   
                        $newBooking= $this->load->view('templates/email-template/new_booking', $emailData, TRUE);
                        $this->email->from($fromEmail); 
                        $this->email->to($customer_mail);  
                        $this->email->subject($subject);
                        $this->email->message($newBooking);
                        $this->email->send();
                    }
                    if(!empty($estimator_mail) && $senttoestimator){
                        $newEstimatorBooking = $this->load->view('templates/email-template/new_booking_estimator', $emailData, TRUE);
                        $this->email->from($fromEmail); 
                        $this->email->to($estimator_mail);  
                        $this->email->subject($subject);
                        $this->email->message($newEstimatorBooking);
                        $this->email->send();
                    }  
                }  
            }
        }
        else{
            return false;
        }
        return true;
    }  

/ функция удаления бронирования /

public function deleteBooking($id){
     $where = array('id'=>$id); 
     $bookingData = $this->Cnc_model->getData('bookings', array('*'), array('id'=>$id)); 
     if(!empty($bookingData)){
        if(!empty($bookingData[0]['estimator_id']) && $bookingData[0]['estimator_id'] != 0){
                    $name = $this->Cnc_model->getData('users',array('username', 'email'), array('user_id'=> $bookingData[0]['estimator_id']));   
                    $estimator_name = $name[0]['username'];
                    $estimator_mail = $name[0]['email']; 
                    }

                if($bookingData[0]['customer_id'] != 0){
                    $cname = $this->Cnc_model->getData('customers',array('name', 'office_contact_email'), array('id'=> $bookingData[0]['customer_id']));   
                    $customer_name = $cname[0]['name'];
                    $customer_mail = $cname[0]['office_contact_email'];
                }
                $mailHeading = 'Booking Deleted';
                $smallHeading = 'Your Booking with '.$customer_name.' on '.$bookingData[0]['booking_date'].' has been deleted by admin.';
                $subject = 'Booking Deleted';
                $smallHeadingcustomer = 'Your Booking with '.$estimator_name.' on '.$bookingData[0]['booking_date'].' has been deleted by admin.';
                $status = 5;

/ * Здесь яя вызываю функцию отправки электронной почты * /

                $result = $this->emailSent($id, $mailHeading, $smallHeading, $subject, $smallHeadingcustomer,$status);

/ * После получения ответа я отправляю ответ на запрос ajax * /

              if($result){
                    $deleteBooking = $this->Cnc_model->rowsDelete('bookings', $where);
                    if($deleteBooking){
                        $this->logThis('Deleted', 'Booking', 'Booking Deleted', array('id' => $id));
                        $this->Cnc_model->addNotification($id,22,$this->auth_user_id,$bookingData[0]['estimator_id'],'Booking Deleted',$bookingData[0]['booking_title'].' deleted on '.date("m/d/Y").' at '.date('H:i a'));
                        $where = '';
                        $data['success'] = true; 
                        $data['message'] = 'Booking deleted successfully.';
                        echo json_encode($data);
                        die;     
                    }else{
                        $where = '';
                        $data['success'] = false; 
                        $data['message'] = 'Error while deleting booking.';
                        echo json_encode($data);
                       die;
                    }
               }  
            }
     else{
        $data['success'] = false; 
        $data['message'] = 'Error while deleting booking.';
        echo json_encode($data);
        die;  
     }
}

Ответы [ 2 ]

0 голосов
/ 02 июля 2019

Вы можете использовать ignore_user_abort (true);Устанавливает, должно ли отключение клиента вызывать прерывание сценария.Это отключит текущее соединение с вашей стороны, а затем отправит ответ клиенту, но все равно выполнит остальную часть кода.

 ignore_user_abort(true);

    ob_start();
    echo "success";

    $serverProtocole = filter_input(INPUT_SERVER, 'SERVER_PROTOCOL', FILTER_SANITIZE_STRING);
    header($serverProtocole.' 200 OK');
    header('Content-Encoding: none');
    header('Content-Length: '.ob_get_length());
    header('Connection: close');

    ob_end_flush();
    ob_flush();
    flush();

Сначала используйте проверку API для своего API, затем используйте приведенный выше код для отправки ответа, после чего вы можете написать код для отправки электронной почты своим пользователям, таким образом, интерфейс получит ответ, а скриптвыполнять до тех пор, пока он не встретит возврат или умереть;проблема с этим методом заключается в том, что вы не можете отправить ответ в веб-интерфейс, если при отправке электронной почты произошла ошибка.

В противном случае вы можете использовать почтовую очередь в своем коде, чтобы выполнить работу позже

0 голосов
/ 02 июля 2019

Зависит от того, насколько глубоко вы хотите зайти. Идеальным способом было бы запустить сервер RabbitMQ или Gearman и настроить задание «отправка почты» для их обработки. Отправка задания выполняется очень быстро и позволит сценарию завершить и отправить ответ обратно пользователю, но, разумеется, это потребует настройки большей инфраструктуры, написания / поддержки большего количества кода для обработки задания и обработки состояний повторения / ошибки.

Вероятно, наименее проблематичным способом было бы запустить локальный почтовый сервер, который будет пересылать почту. Передача должна быть очень быстрой, даст лучший «правильный» ответ (по крайней мере, пользователь будет знать, что почта была отправлена ​​на локальный почтовый сервер) и позволит сценарию продолжиться. В случае сбоя электронной почты он обрабатывается локальным почтовым сервером как отказ администратора или пользователя «от».

Один из описанных способов здесь будет означать отправку ответа сначала , а затем обработку электронного письма, что означает, что он никогда не сможет сообщить о сбое пользователю. Не идеально, но это зависит от вашей ситуации - может быть, администратор обрабатывает ошибочные сообщения и может повторно отправить?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...