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

时间:2013-04-29 21:33:33

标签: php mysql validation queue gearman

我有一个Web表单,我想验证输入,如果它通过验证,将信息发送到Web服务,并保存到mySQL作为备份。如果发送到Web服务或使用sql时出错,我想给自己发送一条警告让我知道。当没有错误时,一切运行正常。为了测试如果出现错误会发生什么,我已经输入了错误的mysql凭据。发生这种情况时,整个脚本大约需要30秒来处理。我想知道在完成脚本之前是否有办法运行验证部分并返回响应。在发送对服务器的响应之后,我想调用Web服务并在后台保存到mysql。这可能吗?我需要实施像齿轮机这样的东西吗?

此外,这将是一个相当高的音量形式。如果两个人同时尝试提交,是否会出现mysql问题?有没有办法更好地提高安全性?我是初学者,所以任何额外的建议都会很棒。

谢谢!

<?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;       
}
}

1 个答案:

答案 0 :(得分:0)

使用JSON和AJAX的Javascript / jQuery是您最好的选择。这里有一个很好的例子:

Send JSON data via POST (ajax) and receive json response from Controller (MVC)

同样安全方面,你会想要使用mysqli_real_escape_string():

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

在将值放入查询之前,通过POST或GET接受的字符串值。它避免了SQL注入。对于整数,使用abs(intval($ _ POST ['posting_integer']))或ctype_digit,无论你需要浮动,还是preg_replace()/ preg_match()正则表达式。

不要让POST或GET值不受影响!