2013-04-29 27 views
0

我有一个Web表单,我想验证输入,如果它通过验证,发送信息到一个Web服务,并保存到mySQL作为备份。如果发送到Web服务或使用SQL发生错误,我想给我发电子邮件一个警告让我知道。当没有错误时,一切运行良好。为了测试如果发生错误会发生什么,我输入了错误的mysql凭据。发生这种情况时,整个脚本需要大约30秒的时间来处理。我想知道在完成脚本之前是否有办法运行验证部分并返回响应。我想调用Web服务并在发送对服务器的响应之后在后台保存到mysql。这可能吗?我是否需要实施像齿轮人这样的东西?PHP中缓慢的表单处理 - 需要队列?

此外,这将是一个相当高的数量形式。如果两个人同时提交,会不会有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;  
} 
} 

回答

0

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

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值不变化到您的数据库!

+0

我将使用Jquery/Ajax进行提交,但我确实希望可以在JS关闭时访问表单。由于我使用的是PDO而不是mySQLi,PDO不会自动进行转义吗? – Evan 2013-04-29 23:00:15

+0

它会执行转义,因为在您的表名中添加了“ticks”,而不是阻止某人传递SELECT/UPDATE/INSERT/DELETE作为子查询。 – Frank 2013-04-30 00:01:32