简体   繁体   English

PHP中的表单处理缓慢-需要队列吗?

[英]Slow Form Processing in PHP - Need Queue?

I have a web form which I want to validate the inputs, and if it passes validation, send the info to a web service, and save to mySQL as a backup. 我有一个要验证输入的Web表单,如果它通过了验证,则将信息发送到Web服务,并保存到mySQL作为备份。 If there is an error either sending to the web service, or with sql, I want to email myself an alert to let me know. 如果发送到Web服务或sql时出现错误,我想通过电子邮件向自己发送警报,让我知道。 When there are no errors, everything runs fine. 没有错误时,一切运行正常。 To test what would happen if there is an error, I have put in the wrong mysql credentials. 为了测试如果出现错误会发生什么,我输入了错误的mysql凭据。 When this happens, the whole script takes about 30 seconds to process. 发生这种情况时,整个脚本大约需要30秒钟来处理。 I'm wondering if there is a way to run the validation part and return the response, before finishing the script. 我想知道是否有一种方法可以在完成脚本之前运行验证部分并返回响应。 I want to call the web service and save to mysql in the background, after the response to the server has been sent. 发送服务器响应后,我想调用Web服务并在后台保存到mysql中。 Is this possible? 这可能吗? Would I need to implement something like gearman? 我需要实施类似Gearman的工具吗?

Also, this would be a fairly high volume form. 同样,这将是一个相当大的数量形式。 If two people tried to submit at the same time, would there be a mysql issue? 如果两个人试图同时提交,是否会有mysql问题? Are there any ways to better improve security? 有什么方法可以更好地提高安全性? I'm a beginner so any extra advice would be great. 我是一个初学者,因此任何其他建议都将是很好的。

Thanks! 谢谢!

<?php
if( isset($_POST) ){
//form validation vars
$formok = true;
$errors = array();

//sumbission data
$ipaddress = $_SERVER['REMOTE_ADDR'];

//
//form data
//

//Services
if(isset($_POST['services'])) {     
    $services = $_POST['services'];
} else {
    $services = array(
        'Neck' => NULL,
        'Back' => NULL,
        'Other' => NULL,
    );
}

$firstname = $_POST['firstname'];   
$lastname = $_POST['lastname']; 
$email = $_POST['email'];

$telephone = $_POST['telephone'];
$TelephoneSanitized = preg_replace("/[^0-9]/", "", $telephone); //format phone as number only

//if phone number does not start with 1, and the length is less than 11 characters, add the 1 to the beginning
if ((substr($TelephoneSanitized, 0, 1) != '1') && (strlen($TelephoneSanitized) < 11)) {
    $TelephoneSanitized = "1".$TelephoneSanitized;      
     }

//$state = strip_tags($_POST['state']);
$location = $_POST['location'];
$message = $_POST['message'];

$leadsource = $_POST['leadsource']; 
$refId = $_POST['refId'];   
$isconsult = $_POST['isconsult'];

//Third Party Emails
if(isset($_POST['receiveThirdPtyEmails'])) {        
    $receiveThirdPtyEmails = strip_tags($_POST['receiveThirdPtyEmails']);
} else {
    $receiveThirdPtyEmails = NULL;      
}

//
//validation
//  

//validate location has been set
if($location == 0){
    $formok = false;
    $errors[] = "Please select your nearest location";
}

//validate name is not empty
if(empty($firstname)){
    $formok = false;
    $errors[] = "Please enter your first name";
}
if(empty($lastname)){
    $formok = false;
    $errors[] = "Please enter your last name";
}

//validate email address is not empty
if(empty($email)){
    $formok = false;
    $errors[] = "Please enter your email address";
//validate email address is valid
}elseif(!filter_var($email, FILTER_VALIDATE_EMAIL)){
    $formok = false;
    $errors[] = "You have not entered a valid email address";
}

//validate phone is not empty
if(empty($telephone)){
    $formok = false;
    $errors[] = "Please enter your phone number";
}
//validate phone is at least 10 characters
elseif(strlen($TelephoneSanitized) < 10){
    $formok = false;
    $errors[] = "Your phone number must be at least 10 characters";
}

//what we need to return back to our form
$returndata = array(
    'posted_form_data' => array(
        'services' => $services,
        'firstname' => $firstname,
        'lastname' => $lastname,
        'email' => $email,
        'telephone' => $telephone,
        //'state' => $state,
        'location' => $location,
        'message' => $message
    ),
    'form_ok' => $formok,
    'errors' => $errors,
);

//if this is not an ajax request  
if(empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest'){  

    //set session variables  
    session_start();  
    $_SESSION['cf_returndata'] = $returndata;  

    //redirect back to form  
    header('location: ' . $_SERVER['HTTP_REFERER']);  

}
//
//send to web service if all is ok
//
if($formok){

    //build query string
    $fields = array('services' => $services,
            'location' => $location,
            'firstname' => $firstname,
            'lastname' => $lastname,
            'email' => $email,
            'emailconfirm' => $email,
            'phone' => $TelephoneSanitized,
            'comments' => $message,
            'refid' => $refId,
            'leadsource' => $leadsource,
            'isconsult' => $isconsult,
            'receiveThirdPtyEmails' => $receiveThirdPtyEmails);

    $url = "http://fake.aspx?" . http_build_query($fields, '', "&");

    $url = preg_replace('/%5B[a-zA-Z]+%5D/', '', $url);

    $curl_handle = curl_init($url);
    curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
    $results = curl_exec($curl_handle);
    curl_close($curl_handle);

}

//
//save data to mysql if all is ok PDO
//
if($formok){

    // Connecting to the MySQL server
    $host="fakehost-on the same server as form";
    $user_name="fakeuser";
    $pwd="fakepass";
    $database_name="fakedb";        

    $services = implode(',',array_filter($services)); // change array to string

    date_default_timezone_set('America/New_York');
    $date = date('m/d/Y h:i:s a', time());
    $date = date("Y-m-d H:i:s",strtotime($date));

    // mysql
    try {  
        //connect to db  
        $conn = new PDO("mysql:host=$host;dbname=$database_name", $user_name, $pwd);
        //set error handling
        $conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
        //prepare statement
        $q = $conn->prepare("INSERT INTO leads 
        (ip_address, lead_time, location, first_name, last_name, email_address, telephone, comments, services, receiveThirdPtyEmails, leadsource, refid) 
        VALUES 
        (:ip_address, :lead_time, :location, :first_name, :last_name, :email_address, :telephone, :comments, :services, :receiveThirdPtyEmails, :leadsource, :refid)");

        //execute statement                 
        $q->execute(array(
            ':ip_address'=>$ipaddress,
            ':lead_time'=>$date,
            ':location'=>$location,
            ':first_name'=>$firstname,
            ':last_name'=>$lastname,
            ':email_address'=>$email,
            ':telephone'=>$TelephoneSanitized,
            ':comments'=>$message,
            ':services'=>$services,
            ':receiveThirdPtyEmails'=>$receiveThirdPtyEmails,
            ':leadsource'=>$leadsource,
            ':refid'=>$refId));

    }  
    catch(PDOException $e) {
        $error_code = $e->getMessage();      // Specify the error code 
        $error_type = "SQL Insert Failed";
        require_once("resources/error-mailer.php");   // Include the error mailer script  
    }  
    # close the connection  
    $conn = null;       
}
}

Javascript/jQuery using JSON and AJAX is your best bet. 使用JSON和AJAX的Javascript / jQuery是您最好的选择。 There's a great example here: 这里有一个很好的例子:

Send JSON data via POST (ajax) and receive json response from Controller (MVC) 通过POST(ajax)发送JSON数据并从Controller(MVC)接收JSON响应

Also security wise, you'll want to use the mysqli_real_escape_string(): 同样在安全方面,您将要使用mysqli_real_escape_string():

http://php.net/manual/en/mysqli.real-escape-string.php http://php.net/manual/zh/mysqli.real-escape-string.php

on strings values you accept via POST or GET before you put the value into your query. 在将值放入查询之前,通过POST或GET接受的字符串值。 It avoids SQL injection. 它避免了SQL注入。 For integers use abs(intval($_POST['posted_integer'])) or ctype_digit, whatever floats your needs, or preg_replace() / preg_match() regular expressions. 对于整数,请使用abs(intval($ _ POST ['posted_integer']))或ctype_digit,无论是需要浮动的内容,还是使用preg_replace()/ preg_match()正则表达式。

DO NOT let POST or GET values go untouched into your database!! 不要让POST或GET值进入数据库!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM