2012-04-18 49 views
2

我有檢查三個字段,姓名,有效的電子郵件和評論的電子郵件的形式。但現在它的設置方式,因爲名稱和註釋在一個函數中,它首先檢查名稱和註釋,即使電子郵件無效,我如何重新編寫它,以便按順序檢查字段。另外,我想重新顯示沒有錯誤的字段,因此用戶不必再次輸入。請幫忙。由於爲了和重新顯示正確的字段PHP顯示錯誤消息

<?php 
$myemail = "[email protected]"; 
$yourname = check_input($_POST['yourname'], "Enter your name!"); 
$email = check_input($_POST['email']); 
$phone = check_input($_POST['phone']); 
$subject = check_input($_POST['subject']); 
$comments = check_input($_POST['comments'], "Write your comments!"); 

if (!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/", $email)) 
    { 
    show_error("Enter a valid E-mail address!"); 
    } 

exit(); 

function check_input($data, $problem='') 
{ 
$data = trim($data); 
$data = stripslashes($data); 
$data = htmlspecialchars($data); 
if ($problem && strlen($data) == 0) 
{ 
    show_error($problem); 
} 
return $data; 
} 

function show_error($myError) 
{ 
?> 
<!doctype html> 
<html> 
<body> 
<form action="myform.php" method="post"> 
<p style="color: red;"><b>Please correct the following error:</b><br /> 
<?php echo $myError; ?></p> 
<p>Name: <input type="text" name="yourname" /></P> 
<P>Email: <input type="text" name="email" /></p> 
<P>Phone: <input type="text" name="phone" /></p><br /> 
<P>Subject: <input type="text" style="width:75%;" name="subject" /></p> 
<p>Comments:<br /> 
<textarea name="comments" rows="10" cols="50" style="width: 100%;"></textarea></p> 
<p><input type="submit" value="Submit"></p> 
</form> 
</body> 
</html> 
<?php 
exit(); 
} 
?> 
+0

我試圖把正則表達式到check_input功能,但隨後的電子郵件錯誤,無論表現。 – Mosaic 2012-04-18 23:11:13

回答

5

首先,我建議您一次驗證所有字段,並在窗體上顯示所有相應的錯誤消息。主要原因是,如果他們必須一次性提交表單,因爲他們必須一次解決一個錯誤,那麼這可能是不好的用戶體驗。我寧願一次嘗試修改我的電子郵件地址,密碼,註釋和選擇,而不是一次修復一個,只是爲了揭示下一個錯誤。

這就是說,這裏有一些關於驗證表單的指針,就像你想要的。這通常是我如何處理表單,做你想做的事情。這假定你的表單HTML和表單處理器(PHP)在同一個文件中(這是你現在擁有的)。你可以將兩者分開,但是做這些的方法可能有點不同。

  • 有一個函數或代碼塊輸出表單並知道您的錯誤消息並且可以訪問以前的表單輸入(如果有的話)。通常,這可以留在函數之外,並且可以是PHP腳本中的最後一段代碼。
  • 設置錯誤消息的數組(例如$errors = array())。當此數組爲空時,您知道提交時沒有錯誤
  • 檢查表單是否在輸出表單之前在腳本頂部附近提交。
  • 如果表單提交,驗證每個字段中的一個在一個時間,如果字段包含一個錯誤,添加錯誤消息發送到所述$errors陣列(例如$errors['password'] = 'Passwords must be at least 8 characters long';
  • 要重新填充與以前的值的形式輸入,您可以選擇存儲所輸入的值的地方(你可以只使用$_POST陣列,或消毒並分配$_POST值將各個變量或數組。
  • 一旦所有的處理完成後,你可以檢查任何錯誤決定是否可以在此處處理表單,或者需要用戶提供新的輸入。
  • 要做到這一點,我通常會做一些類似於if (sizeof($errors) > 0) { // show messages } else { // process form }
  • 如果要重新顯示錶單,只需將value=""屬性添加到每個表單元素並回顯用戶提交的值。 使用用htmlspecialchars()或類似的功能

有了這些東西逃跑的輸出是非常重要的,這是你的形式的一些重新工作要做到這一點:

<?php 
$myemail = "[email protected]"; 
$errors = array(); 
$values = array(); 
$errmsg = ''; 

if ($_SERVER['REQUEST_METHOD'] == 'POST') { 
    foreach($_POST as $key => $value) { 
     $values[$key] = trim(stripslashes($value)); // basic input filter 
    } 

    if (check_input($values['yourname']) == false) { 
     $errors['yourname'] = 'Enter your name!'; 
    } 

    if (check_input($values['email']) == false) { 
     $errors['email'] = 'Please enter your email address.'; 
    } else if (!preg_match('/([\w\-]+\@[\w\-]+\.[\w\-]+)/', $values['email'])) { 
     $errors['email'] = 'Invalid email address format.'; 
    } 

    if (check_input($values['comments']) == false) { 
     $errors['comments'] = 'Write your comments!'; 
    } 

    if (sizeof($errors) == 0) { 
     // you can process your for here and redirect or show a success message 
     $values = array(); // empty values array 
     echo "Form was OK! Good to process...<br />"; 
    } else { 
     // one or more errors 
     foreach($errors as $error) { 
      $errmsg .= $error . '<br />'; 
     } 
    } 
} 

function check_input($input) { 
    if (strlen($input) == 0) { 
     return false; 
    } else { 
     // TODO: other checks? 

     return true; 
    } 
} 
?> 
<!doctype html> 
<html> 
<body> 
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post"> 
<?php if ($errmsg != ''): ?> 
<p style="color: red;"><b>Please correct the following errors:</b><br /> 
<?php echo $errmsg; ?> 
</p> 
<?php endif; ?> 

<p>Name: <input type="text" name="yourname" value="<?php echo htmlspecialchars(@$values['yourname']) ?>" /></P> 
<P>Email: <input type="text" name="email" value="<?php echo htmlspecialchars(@$values['email']) ?>" /></p> 
<P>Phone: <input type="text" name="phone" value="<?php echo htmlspecialchars(@$values['phone']) ?>"/></p><br /> 
<P>Subject: <input type="text" style="width:75%;" name="subject" value="<?php echo htmlspecialchars(@$values['subject']) ?>" /></p> 
<p>Comments:<br /> 
<textarea name="comments" rows="10" cols="50" style="width: 100%;"><?php echo htmlspecialchars(@$values['comments']) ?></textarea></p> 
<p><input type="submit" value="Submit"></p> 
</form> 
</body> 
</html> 

我有一個更高級的例子,你可以看到here也可以給你一些指導。

希望有所幫助。

+0

完美的作品!並感謝您的詳細解釋。 – Mosaic 2012-04-19 02:27:09

+0

好的頭像;)。幸運的是,我們使用頻繁的不同房間在stackoverflow上。 – 2016-06-16 10:30:48

+0

@terencehill * thumbsup * :) – drew010 2016-06-16 16:29:48

1

使用腳本的這種結構:

<?php 
$errors = array(); 

if (isset($_POST['send'])) { 
    // check data validity 
    if (!mailValid($_POST['email'])) 
     $errors[] = 'Mail is not valid'; 
    ... 

    // send data by email 
    if (!$errors) { 
     // send mail and redirect 
    } 
} 
?> 
<html> 
    ... 
    <?php 
    if ($errors) { 
     // display errors 
     foreach ($errors as $error) { 
      echo "$error<br />"; 
     } 
    } 
    ?> 
    <form ...> 
     ... 
     Email: <input type="text" name="email" value="<?php echo isset($_POST['email']) ? htmlspecialchars($_POST['email']) : '' ?>" /> 
     ... 
    </form> 
    ... 
</html> 
1

最簡單的方法是使用form validation library。例如,PHP的filter擴展可爲某些類型提供驗證和消毒,但它不是一個完整的解決方案。

如果您堅持自己實現它,您需要考慮的一個問題是:順序是什麼:表單中元素的順序或$_POST中用戶輸入的順序。在大多數瀏覽器上,這些應該是相同的,但沒有標準強制執行此操作。如果你不想使用表單命令,你需要在一個地方定義表單結構,並使用這些信息來完成生成或驗證表單的工作(這是乾燥原理的結果)。遍歷適當的結構會給你你想要的順序:循環遍歷表單給你的表單順序,而循環結束$_POST給你用戶輸入順序。

看起來要更不是簡單地對數據進行驗證;你也想準備使用它,這個過程叫做「消毒」。

當談到消毒,定義不同類型消毒劑的,而不是單一的check_input功能。具體的消毒殺菌劑可能是功能,或與__invoke方法的對象。創建一個表單字段到衛生消毒劑的映射(例如,一個輸入名稱到衛生消毒劑回調的數組)。映射中元素的順序設置了清理的順序;如果您使用單個結構來定義表單信息,則顯示順序和清理順序將相同。

這裏是一個非常廣泛的輪廓:

# $fields could be form structure or user input 
foreach ($fields as $name => $data) { 
    # sanitize dispatches to the appropriate sanitizer for the given field name 
    $form->sanitize($name, $data); 
    # or: 
    //sanitize($name, $data); 
    # or however you choose to structure your sanitization dispatch mechanism 
} 

作爲輸出元件當輸入的值設置爲用戶提供的數據,簡單地輸出的元素值。與所有用戶輸入(實際上是所有格式化的輸出)一樣,在輸出時正確地轉義數據。對於HTML屬性,這意味着使用(例如)htmlspecialchars。請注意,您應該只轉義傳出數據。這意味着你的消毒功能不應該叫htmlspecialchars

你可以通過把每個錯誤旁相應的輸入,增加一個「錯誤」類別的元素和造型的「錯誤」類,使它脫穎而出提高可用性。通過在標籤文本週圍包裹<label>元素來提高可訪問性。

+0

我是PHP新手,非常感謝您的信息。謝謝! – Mosaic 2012-04-19 01:33:27

1

你總是可以像這樣做,使用filter_varin_array檢查:

<?php 
$myemail = "[email protected]"; 

//Pre made errors array 
$errors=array('name'=>'Enter Your name', 
       'email'=>'Please enter valid email', 
       'phone'=>'Please enter valid phone number', 
       'subject'=>'Please enter valid subject, more then 10 chars', 
       'comment'=>'Please enter valid comment, more then 10 chars'); 

//Allowed post params and its validation type 
$types = array('name'=>'string', 
       'email'=>'email', 
       'phone'=>'phone', 
       'subject'=>'string', 
       'comment'=>'string'); 

//A simple validation function using filter_var 
function validate($value,$type){ 
    switch ($type){ 
     case "email": 
      return ((filter_var($value, FILTER_VALIDATE_EMAIL))?true:false); 
      break; 
     case "phone": 
      return ((preg_match("/^[0-9]{3}-[0-9]{4}-[0-9]{4}$/", $value))?true:false); 
      break; 
     case "string": 
      return ((strlen($value) >=10)?true:false); 
      break; 

     default: 
      return false; 
      break; 
    } 
} 


//If forms been posted 
if(!empty($_POST) && $_SERVER['REQUEST_METHOD'] == 'POST'){ 
    //Assign true, if all is good then this will still be true 
    $cont=true; 
    $error=array(); 
    foreach($_POST as $key=>$value){ 
     //if key is in $types array 
     if(in_array($key,$types)){ 
     //If validation true 
     if(validate($value, $types[$key])==true){ 
      $$key=filter_var($value, FILTER_SANITIZE_STRING); 
     }else{ 
      //Validation failed assign error and swithc cont to false 
      $error[$key]=$errors[$key]; 
      $cont=false; 
     } 
     } 
    } 
} 

if($cont==true && empty($error)){ 
    //Send mail/do insert ect 
}else{ 
    //Default to form 
?> 
<!doctype html> 
<html> 
<body> 
<form action="" method="post"> 
<p>Name: <input type="text" name="name" value="<[email protected]($name);?>"/> <[email protected]$error['name'];?></P> 
<P>Email: <input type="text" name="email" value="<[email protected]($email);?>" /> <[email protected]$error['email'];?></p> 
<P>Phone: <input type="text" name="phone" value="<[email protected]($phone);?>"/> <[email protected]$error['phone'];?></p><br /> 
<P>Subject: <input type="text" style="width:75%;" name="subject" /> <[email protected]$error['subject'];?></p> 
<p>Comments: <[email protected]$error['comment'];?><br /> 
<textarea name="comment" rows="10" cols="50" style="width: 100%;"><[email protected]($comment);?></textarea></p> 
<p><input type="submit" value="Submit"></p> 
</form> 
</body> 
</html> 
<?php 
}?>