aolong Posted May 27, 2009 Share Posted May 27, 2009 I have a form which submits data to a MySQL db, prints out a summary, and sends an email summary of the submission. Everything works, but due to my own lack of experience, I have written the validation in very piecemeal fashion, not very elegant. Rather than doing a lot of individual checks which return a message and die, I want to combine the validations and return one summary of the errors (if present) OR continue with the submission. If this is too involved, I am perfectly ok with suggestions for reading or examples. Here is the validation block from the php page which receives the form data and then does the work: [pre] // ---------- START VALIDATIONS ------------- // validate the mac-address. This will also match lower-case a-f, // but we passed the mac through strtoupper above. if (! preg_match('/^[A-Fa-f0-9]{2}\-[A-Fa-f0-9]{2}\-[A-Fa-f0-9]{2}\-[A-Fa-f0-9]{2}\-[A-Fa-f0-9]{2}\-[A-Fa-f0-9]{2}$/i', $rightMac)) { echo "Invalid Mac-Address: please go back and correct."; die; } // validate the "expires" field is not empty if (empty($expires)) { echo 'Expiration is a required field: please go <a href="javascript: history.go(-1)">Back</a> and correct.'; die; } // validate the "expires" field is in form yyyy-mm-dd if (! preg_match('/^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/i', $_POST['expires'])) { echo 'Invalid expiration date (must be yyyy-mm-dd): please go <a href="javascript: history.go(-1)">Back</a> and correct.'; die; } /* // check that the expires field is a valid date $splitExpires=split("-",$expires); //split the expires field $yy=$arr[0]; // first element is year $mm=$arr[1]; // second argument is month $dd=$arr[3]; // third argument is day if(!checkdate($yy,$mm,$dd)){ echo "$expires is an invalid date: please go <a href='javascript: history.go(-1)'>Back</a> and correct."; die; } */ // make sure a property was chosen if ($friendlyName == "?Property?") { echo 'You did not select a property: please go <a href="javascript: history.go(-1)">Back</a> and correct.'; die; } // validate the "agentFirstName" field is not empty if (empty($agentFirstName)) { echo 'Agent First Name is a required field: please go <a href="javascript: history.go(-1)">Back</a> and correct.'; die; } // validate the "agentLastName" field is not empty if (empty($agentLastName)) { echo 'Agent Last Name is a required field: please go <a href="javascript: history.go(-1)">Back</a> and correct.'; die; } // ---------- END VALIDATIONS -----------[/pre] Thank you, and let me know if it helps to post more of the form (I omitted because there's alot of stuff I'd have to obfuscate). A. Quote Link to comment Share on other sites More sharing options...
gevans Posted May 27, 2009 Share Posted May 27, 2009 Instead of printing out the error and killing the script like this; echo "Invalid Mac-Address: please go back and correct."; die; Assign the error to an array; $errors[] = "Invalid Mac-Address: please go back and correct.<br />\r\n"; Note the line break at the end. Then after your validation is done check if there is an error; <?php if(is_array($errors)){ foreach($errors as $error) { echo $error; } } Quote Link to comment Share on other sites More sharing options...
GingerRobot Posted May 27, 2009 Share Posted May 27, 2009 You also make your life a lot easier by having forms submit to themselves. You place the processing of the form at the top of the page and can then output the errors where you want. E.g.: <?php $errors = array(); if(count($_POST) > 0){ //form's been submitted...deal with it //check all our errors if(count($errors)==0){ //submit into database. Redirect to thank you page/redisplay blank form/whatever } } ?> Your HTML header goes here Say you want errors to show here: <?php if(count($errors > 0)){ //display them } ?> Show your form: <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post"> You can also set the value of the field to whatever the user typed...that way they only have to correct the field that was wrong. Eg: <input type="text" value="<?php echo (isset($_POST['age'])) ? $_POST['age'] : ''; ?>" name="age" /> Quote Link to comment Share on other sites More sharing options...
aolong Posted May 27, 2009 Author Share Posted May 27, 2009 Instead of printing out the error and killing the script like this; echo "Invalid Mac-Address: please go back and correct."; die; Assign the error to an array; $errors[] = "Invalid Mac-Address: please go back and correct.<br />\r\n"; Note the line break at the end. Then after your validation is done check if there is an error; <?php if(is_array($errors)){ foreach($errors as $error) { echo $error; } } Any chance you can show me this again with another validation piled on... I don't see how I would build up the combined error message with each successive test. And thanks for the hint... A. Quote Link to comment Share on other sites More sharing options...
gevans Posted May 27, 2009 Share Posted May 27, 2009 here's an example of how the first two tests would look; if (empty($expires)) { $errors[] = 'Expiration is a required field: please go <a href="javascript: history.go(-1)">Back</a> and correct.'; } // validate the "expires" field is in form yyyy-mm-dd if (! preg_match('/^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/i', $_POST['expires'])) { $errors[] = 'Invalid expiration date (must be yyyy-mm-dd): please go <a href="javascript: history.go(-1)">Back</a> and correct.'; } Quote Link to comment Share on other sites More sharing options...
aolong Posted May 27, 2009 Author Share Posted May 27, 2009 Do you mean... if (empty($expires)) { $errors[] = 'Expiration is a required field: please go <a href="javascript: history.go(-1)">Back</a> and correct. <br />' \r\n; } // validate the "expires" field is in form yyyy-mm-dd if (! preg_match('/^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/i', $_POST['expires'])) { $errors[] = 'Invalid expiration date (must be yyyy-mm-dd): please go <a href="javascript: history.go(-1)">Back</a> and correct.' \r\n; } I think I miffed the quoting, my point was to include the line breaks... A. Quote Link to comment Share on other sites More sharing options...
aolong Posted May 27, 2009 Author Share Posted May 27, 2009 Here's what I ended up with... probably still crude but it works better than before. Thanks for the help. Now on to formatting the error message. // ---------- START VALIDATIONS ------------- // validate the mac-address. This will also match lower-case a-f, // but we passed the mac through strtoupper above. if (! preg_match('/^[A-Fa-f0-9]{2}\-[A-Fa-f0-9]{2}\-[A-Fa-f0-9]{2}\-[A-Fa-f0-9]{2}\-[A-Fa-f0-9]{2}\-[A-Fa-f0-9]{2}$/i', $rightMac)) { // echo "Invalid Mac-Address: please go back and correct."; // die; $errors[] = "- Invalid Mac-Address! <br /> \r\n"; } // validate the "expires" field is not empty if (empty($expires)) { // echo 'Expiration is a required field: please go <a href="javascript: history.go(-1)">Back</a> and correct.'; // die; $errors[] = "- Expiration is a required field! <br /> \r\n"; } // validate the "expires" field is in form yyyy-mm-dd if (! preg_match('/^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/i', $_POST['expires'])) { // echo 'Invalid expiration date (must be yyyy-mm-dd): please go <a href="javascript: history.go(-1)">Back</a> and correct.'; // die; $errors[] = "- Invalid expiration date (must be yyyy-mm-dd)! <br /> \r\n"; } /* this does not work for some reason... // check that the expires field is a valid date $splitExpires=split("-",$expires); //split the expires field $yy=$arr[0]; // first element is year $mm=$arr[1]; // second argument is month $dd=$arr[3]; // third argument is day if(!checkdate($yy,$mm,$dd)){ echo "$expires is an invalid date: please go <a href='javascript: history.go(-1)'>Back</a> and correct."; die; } */ // make sure a property was chosen if ($friendlyName == "?Property?") { // { echo 'You did not select a property: please go <a href="javascript: history.go(-1)">Back</a> and correct.'; // die; $errors[] = "- You did not select a property! <br /> \r\n"; } // validate the "agentFirstName" field is not empty if (empty($agentFirstName)) { // echo 'Agent First Name is a required field: please go <a href="javascript: history.go(-1)">Back</a> and correct.'; // die; $errors[] = "- Agent First Name is a required field! <br /> \r\n"; } // validate the "agentLastName" field is not empty if (empty($agentLastName)) { // echo 'Agent Last Name is a required field: please go <a href="javascript: history.go(-1)">Back</a> and correct.'; // die; $errors[] = "- Agent Last Name is a required field!<br /> \r\n"; } // ---------- END VALIDATIONS ----------- // define the function to print our page header function page_header() { print ' <html> <head> <title>ForceAuth Results</title> <link rel="stylesheet" href="styles.css" type="text/css" media="screen"> <style type="text/css"> <!-- body { margin: 20px 10px ; } table { margin-bottom:15px; } table td { white-space: nowrap; } --> </style> </head> <body>'; } function page_footer() { print ' </body></html> '; } page_header(); //print the header if(is_array($errors)){ echo "<h3>Errors:</h3>"; } if(is_array($errors)){ foreach($errors as $error) { echo $error; } } if(is_array($errors)){ echo "<p><em>Please go <a href='javascript: history.go(-1)'>Back</a> and correct.</p>"; die; } Andrew Quote Link to comment Share on other sites More sharing options...
gevans Posted May 28, 2009 Share Posted May 28, 2009 You can trim the end down a bit; if(is_array($errors)){ echo "<h3>Errors:</h3>"; } if(is_array($errors)){ foreach($errors as $error) { echo $error; } } if(is_array($errors)){ echo "<p><em>Please go <a href='javascript: history.go(-1)'>Back</a> and correct.</p>"; die; } could be <?php if(is_array($errors)){ echo "<h3>Errors:</h3>"; foreach($errors as $error) { echo $error; } echo "<p><em>Please go <a href='javascript: history.go(-1)'>Back</a> and correct.</p>"; die; } Quote Link to comment Share on other sites More sharing options...
aolong Posted May 28, 2009 Author Share Posted May 28, 2009 Hey, thanks for the input. You've gone an extra few steps and helped me learn a bit about coding. Appreciate it! Here's what I got; seems to work well with formatting from an alternate css and header for errors: ... // define the function to print our error page header function page_header_error() { print ' <html> <head> <title>Form Errors</title> <link rel="stylesheet" href="styles_error.css" type="text/css" media="screen"> </head> <body>'; } function page_footer() { print '</body> </html>'; } // display errors if present... if(is_array($errors)){ page_header_error(); echo "<p>The following problems were detected with your submission:</p> <ul>"; foreach($errors as $error) { echo "<li>$error</li>"; } echo "</ul> <p><em>Please go <a href='javascript: history.go(-1)'>Back</a> and correct.</p> </body> </html> "; die; } // if no errors, processing starts here... page_header(); //print the header print $message; // print the message ... Quote Link to comment Share on other sites More sharing options...
gevans Posted May 28, 2009 Share Posted May 28, 2009 You could go a step further to make your code a little more re-usable on a page by page basis. Instead of putting a function in place for the header, put it in seperate html files. Then include the file with a simple line of code. This way if you need to update your header you only have to change the html file, not every version of the function. <?php if(is_array($errors)){ //page_header_error(); //above line replace with echo file_get_contents('directory_to_your_file/error_header.html'); echo "<p>The following problems were detected with your submission:</p> <ul>"; foreach($errors as $error) { echo "<li>$error</li>"; } echo "</ul> <p><em>Please go <a href='javascript: history.go(-1)'>Back</a> and correct.</p> </body> </html> "; die; } Then error_header.html would simply be <html> <head> <title>Form Errors</title> <link rel="stylesheet" href="styles_error.css" type="text/css" media="screen"> </head> <body> You could just as easily store the function in a different file and include that wherever it's needed. There are lots of options. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.