tefuzz Posted April 6, 2009 Share Posted April 6, 2009 Ok, as stated in my previous topics, i am new to PHP. With help from some eBooks and topics here I was able to create a contact page, and an email function. this page can be seen here: http://www.dpserror.com/index.php?p=contact (yes i know the CSS is not complete, haven't hacked it for IE yet) I am using 2 pages to accomplish this, contact.php and contact2.php As you can see, It checks the fields and creates an error array accordingly, then checks to see if the array exists. If it does, it runs a series of if statements to determine which error is present, and echo's the correct snippet of code for each one correct or incorrect. This works great for this small form. My issue now is that I have a form with around 30 different elements I need to validate for a different page, with text boxes, radio buttons, and drop down lists. I was going to use the same type of system to validate it too, but I'm going to end up with what I feel is way too much extra code. Can this be done in PHP or am I looking more at a js or ajax type validation, with PHP as a backup in case javascript is turned off in the browser? The thing I am hung up on is, if I use a function to validate each field, and I return and error, How would I go about creating the error in the right place on the form (getting the same result as I was before). Sorry for the long post, I hope I got all the details about what I am trying to do in here. Thanks in advance for the help. the code for contact.php (just the form section): <div id="contactForm"> <!-- contact form --> <table width="400" border="0" cellpadding="5" cellspacing="0"> <form name="contact" class="myform" method="post" action="index.php?p=contact&a=submit"> <input type="hidden" name="sub" /> <!-- make sure form is posted --> <tr> <td width="150"> <label>Full Name <span class="small">first & last</span></label></td> <td width="250"><input name="name" type="text" id="name" tabindex="1" dir="ltr" lang="en" maxlength="65" /></td> </tr> <tr> <td><label>Email Address <span class="small">your@email.com</span></label></td> <td><input name="email" type="text" id="email" tabindex="2" dir="ltr" lang="en" maxlength="65" /></td> </tr> <tr> <td><label>Telephone <span class="small">xxx-xxx-xxxx</span></label></td> <td><input name="phone" type="text" id="phone" dir="ltr" lang="en" maxlength="12" /></td> </tr> <tr> <td><label>How should we contact you?<span class="small">phone or email?</span></label></td> <td><input name="prefPhone" type="checkbox" id="prefPhone" label="Telephone" /> <span class="checkLabel">By Telephone <input type="checkbox" name="prefEmail" id="prefEmail" /> By E-Mail</span></td> </tr> <tr> <td valign="top"><label>Comments<span class="small">or questions?</span></label></td> <td><textarea name="comments" cols="30" rows="7" tabindex="4"></textarea></td> </tr> <tr><td> </td><td><button type="reset">Clear</button> <button type="submit">Submit</button></td> </tr> </form> </table> </div> <!--contact form --> the code for contact2.php: <?php $fname = $_POST['name']; $ftel = $_POST['phone']; $femail = $_POST['email']; if (isset($_POST['prefPhone']) && isset($_POST['prefEmail'])) { // check the checkboxes to see which one(s) are checked $fpref= 'Telephone & E-mail'; // if both are checked = 3 } // if email is checked = 2 elseif (isset($_POST['prefPhone']) && !isset($_POST['prefEmail'])) { // if telephone is checked = 1 $fpref = 'Telephone'; } elseif (!isset($_POST['prefPhone']) && isset($_POST['prefEmail'])) { $fpref = 'E-mail'; } if (empty($fname) or strlen($fname)<3) { $errArray = array('nameError'=>'1'); } if (empty($ftel) or strlen($ftel)<10) { $errArray['telError']='1'; } if (empty($femail) or !preg_match('/^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\@([a-z0-9])' . '(([a-z0-9-])*([a-z0-9]))+' . '(\.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$/i', $femail)) { $errArray['emailError']='1'; } if (!isset($errArray)) { if (contactEmail($fname, $femail, $ftel, $fpref, $fcomment)) { echo 'the email was sent succesfully'; } else { echo 'please try to submit your form again'; } } else { echo '<div id="contactUs"> <!-- beginning of the contact us page code --> <div class="Row"><!-- top row--> </div><!--top row--> <div id="leftCol"><!-- left column--> <h1>Contacting us is easy! </h1> <p><br /> If you have questions you can always check out our <a href="index.php?p=faq">"Frequently Asked Questions"</a>. If our FAQ does not get you the answers you need, you can contact us by phone, by mail, or by using our contact form. We respond to each and every inquiry we receive as soon as possible.<br /> </p> <p><br /> If you would like to contact us by telephone, you can call us any time at the number below. If we are unavailable or it is outside normal business hours please be sure to leave a message with your name, telephone number, and the nature of your call. We will respond to your inquiry at our earliest convenience. </p> <br /> Call us at <span class="boldLabel">770-668-6895</span> <p><br /> If you prefer to contact us by mail, you can do so to the following address: </p> <br /> <span class="boldLabel">Mind Garden Tutoring<br /> PO Box 2421<br /> Acworth, GA 30102</span><br /> <br /> </p> </div><!-- left column --> <div id="contactForm"> <!-- contact form --> <table width="400" border="0" cellpadding="5" cellspacing="0"> <form name="contact" class="myform" method="post" action="index.php?p=contact&a=submit"> <input type="hidden" name="sub" /> <!-- make sure form is posted --> <tr>'; if(isset($errArray['nameError'])) { echo '<td width="150"> <label>Full Name <span class="small">first & last</span></label></td> <td width="250"><input name="name" type="text" id="name" tabindex="1" dir="ltr" lang="en" maxlength="65" /><span class="smallError">* required</span></td> </tr>'; } else { echo ' <td width="150"><label>Full Name <span class="small">first & last</span></label></td> <td width="250"><input name="name" type="text" id="name" value="' . $fname . '" tabindex="1" dir="ltr" lang="en" maxlength="65" /></td> </tr>'; } if(isset($errArray['emailError'])) { echo '<tr> <td><label>Email Address <span class="small">your@email.com</span></label></td> <td><input name="email" type="text" id="email" tabindex="2" dir="ltr" lang="en" maxlength="65" /><span class="smallError">* required</span></td> </tr>'; } else { echo '<tr> <td><label>Email Address <span class="small">your@email.com</span></label></td> <td><input name="email" type="text" value="' . $femail . '" id="email" tabindex="2" dir="ltr" lang="en" maxlength="65" /></td> </tr>'; } if (isset($errArray['telError'])) { echo '<tr> <td><label>Telephone <span class="small">xxx-xxx-xxxx</span></label></td> <td><input name="phone" type="text" id="phone" dir="ltr" lang="en" maxlength=12" /><span class="smallError">* required</span></td> </tr>'; } else { echo '<tr> <td><label>Telephone <span class="small">xxx-xxx-xxxx</span></label></td> <td><input name="phone" type="text" id="phone" value="' . $ftel . '" dir="ltr" lang="en" maxlength=12" /></td> </tr>'; } if (!isset($fpref)) { echo '<tr> <td><label>How should we contact you?<span class="small">phone or email?</span></label></td> <td><input name="prefPhone" type="checkbox" id="prefPhone" label="Telephone" /> <span class="checkLabel">By Telephone <input type="checkbox" name="prefEmail" id="prefEmail" /> By E-Mail</span></td> </tr>'; } if (isset($fpref)) { if ($fpref=='Telephone & E-mail') { echo '<tr> <td><label>How should we contact you?<span class="small">phone or email?</span></label></td> <td><input name="prefPhone" type="checkbox" checked="checked" id="prefPhone" label="Telephone" /> <span class="checkLabel">By Telephone <input type="checkbox" name="prefEmail" checked="checked" id="prefEmail" /> By E-Mail</span></td> </tr>'; } elseif ($fpref=='E-mail') { echo '<tr> <td><label>How should we contact you?<span class="small">phone or email?</span></label></td> <td><input name="prefPhone" type="checkbox" id="prefPhone" label="Telephone" /> <span class="checkLabel">By Telephone <input type="checkbox" name="prefEmail" checked="checked" id="prefEmail" /> By E-Mail</span></td> </tr>'; } elseif ($fpref=='Telephone') { echo '<tr> <td><label>How should we contact you?<span class="small">phone or email?</span></label></td> <td><input name="prefPhone" type="checkbox" checked="checked" id="prefPhone" label="Telephone" /> <span class="checkLabel">By Telephone <input type="checkbox" name="prefEmail" id="prefEmail" /> By E-Mail</span></td> </tr>'; } } if (!isset($fcomment) or strlen($fcomment)==0) { echo '<tr> <td valign="top"><label>Comments<span class="small">or questions?</span></label></td> <td><textarea name="comments" cols="30" rows="7" tabindex="4"></textarea></td> </tr>'; } else { echo '<tr> <td valign="top"><label>Comments<span class="small">or questions?</span></label></td> <td><textarea name="comments" cols="30" rows="7" tabindex="4">' . $fcomment . '</textarea></td> </tr>'; } echo' </tr> <tr><td> </td><td><button type="reset">Clear</button> <button type="submit">Submit</button></td> </tr> </form> </table> </div> <!--contact form --> </div> <!--bottom row --> </div> <!-- end of contact us page -->'; } //this is the closing bracket for the IF statement to check whether the $errArray is set ?> Quote Link to comment https://forums.phpfreaks.com/topic/152902-there-must-be-a-better-wayforms/ Share on other sites More sharing options...
Brian W Posted April 7, 2009 Share Posted April 7, 2009 umm, maybe something like this may be effective. <?php $fields = array('Full Name' => 'name', 'Email Address' => 'email', 'Telephone' => 'phone'); //list of all fields if(!preg_match('/^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\@([a-z0-9])' . '(([a-z0-9-])*([a-z0-9]))+' . '(\.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$/i', $femail)){ $errors['email'] = "Invalid Email Address"; } $required = array('name', 'email');//array of required fields foreach($required as $name){ if($_POST[$name] <= ''){ $errors[$name] = "$field cannot be left empty."; } } if(count($errors)==0){ //go on with code } else { //If there is erros echo "<span style='color:red;'>\n"; foreach($errors as $error){ echo "<li>$error</li>\n"; } echo "</span>\n<form method='post'>"; echo "<table>"; foreach($fields as $field => $name){ if(is_numeric($field)){ $field = $name; } echo '<tr> <td width="150"> <label>'.$field.'</label></td> <td width="250"><input name="'.$name.'" type="text" id="'.$name.'" tabindex="1" dir="ltr" lang="en" maxlength="65" value="'.$_POST[$name].'"/>'; if(isset($errors[$name])){ echo $errors[$name]; } echo '</td> </tr> <tr>' ; } echo "</table>"; echo "<input type='submit'>"; echo "</form>"; } ?> Good luck, I'm signing out for the day. Quote Link to comment https://forums.phpfreaks.com/topic/152902-there-must-be-a-better-wayforms/#findComment-803021 Share on other sites More sharing options...
mosey22 Posted April 7, 2009 Share Posted April 7, 2009 A couple comments: First, it is generally a good thing to avoid duplicating so much code, be it php or html. What happens if you want to add a new field later? You'd have to find and update your form html in (from the looks of it) three places, one on contact.php, and one each for the error and no-error versions in contact2.php. The bad news is that cleaning this up does involve some more advanced stuff than what you're doing. If I were being asked to do this, I would do a few things: Make php code to generate the form elements, rather than including them explicitly in the file as html. The simple way to do this would be to create a function or two that echoed the form html, and took some stuff like field label and field name as parameters, ie function textField($label, $name, [...other params you might want to add, like that small text or maxlength]) { echo("<tr><td width="150"> <label>$label</label></td> <td width="250"><input name="$name" type="text" id="$name" tabindex="1" dir="ltr" lang="en" maxlength="65" /></td> </tr>"); } Then you could use this for each field: (opening stuff in contact.php)... <form name="contact" class="myform" method="post" action="index.php?p=contact&a=submit"> <input type="hidden" name="sub" /> <!-- make sure form is posted --> <?php textField("First Name", "name"); textField("Email Address", "email"); textField("Telephone", "phone"); . . etc . Of course this is somewhat simplified, you might want to add extra parameters to the function for other things that change, or even for other input controls besides input type="text", and also you'll need to \" escape the double-quotes that need to be in the html, I was too lazy... Doing this alone, and placing this function in a file that is include()ed mutually by contact.php and contact2.php would drop down on code duplication, but does not solve the problem of showing users where the error(s) are. The fix is to modify the textField function to automatically add the error when it has been set in your $errArray: function textField($label, $name, [...other params you might want to add, like that small text or maxlength]) { global $errArray; echo("<tr><td width="150"> <label>$label</label></td> <td width="250"><input name="$name" type="text" id="$name" tabindex="1" dir="ltr" lang="en" maxlength="65" />"); if(isset($errArray[$name])) { echo "<span class=\"smallError\">* required</span>"; } echo("</td></tr>"); } Then, in contact2.php, you can run the same logic you already have to ensure form fields are valid, but call this function as shown above to write the form. The if statement in the function will add the error text where there are array entries set. (A slight variation is to set the array entry to the text specifically describing the error, and then echo $errArray[$name] rather than a simple * required) The other thing I would do is stuff $errArray in a session variable in contact2.php after it has gone through all of its logic, and redirect back contact.php if contact2.php found any errors in the form. This further reduces code duplication because in this way only contact.php would be calling the textField function (and thus only contact.php has the form fields and their order specified), but sessions and http redirects are somewhat more advanced. I'm sure this site can offer you assistance on both if you are interested in pursuing this. Hope that gets you started. Quote Link to comment https://forums.phpfreaks.com/topic/152902-there-must-be-a-better-wayforms/#findComment-803031 Share on other sites More sharing options...
mrMarcus Posted April 7, 2009 Share Posted April 7, 2009 make sure to add some $_POST form cleaning, especially some strip_tags() : your Full Name field is vulnerable... [attachment deleted by admin] Quote Link to comment https://forums.phpfreaks.com/topic/152902-there-must-be-a-better-wayforms/#findComment-803052 Share on other sites More sharing options...
tefuzz Posted April 7, 2009 Author Share Posted April 7, 2009 make sure to add some $_POST form cleaning, especially some strip_tags() : your Full Name field is vulnerable... what the?...how did you even do that? ??? Quote Link to comment https://forums.phpfreaks.com/topic/152902-there-must-be-a-better-wayforms/#findComment-803062 Share on other sites More sharing options...
mrMarcus Posted April 7, 2009 Share Posted April 7, 2009 don't worry, no malicious intent on this end whatsoever .. just a simple XSS exploit. i just inputted " />anything i want here into your form field(s) .. Full Name wasn't secure whatsoever. look into securing your forms using strig_tags(), mysql_real_escape_string(), etc...'cause that could've been Javascript or some SQL Injection, and that could be a whole world of hurt. Quote Link to comment https://forums.phpfreaks.com/topic/152902-there-must-be-a-better-wayforms/#findComment-803073 Share on other sites More sharing options...
tefuzz Posted April 7, 2009 Author Share Posted April 7, 2009 don't worry, no malicious intent on this end whatsoever .. just a simple XSS exploit. i just inputted " />anything i want here into your form field(s) .. Full Name wasn't secure whatsoever. look into securing your forms using strig_tags(), mysql_real_escape_string(), etc...'cause that could've been Javascript or some SQL Injection, and that could be a whole world of hurt. will do, thanks for the heads up. Quote Link to comment https://forums.phpfreaks.com/topic/152902-there-must-be-a-better-wayforms/#findComment-803078 Share on other sites More sharing options...
tefuzz Posted April 7, 2009 Author Share Posted April 7, 2009 In my contact2.php i changed $fname = $_POST['name']; $ftel = $_POST['phone']; $femail = $_POST['email']; to this: $fname = strip_tags($_POST['name']); $ftel = strip_tags($_POST['phone']); $femail = strip_tags($_POST['email'], '@.'); when I insert some extra characters like your example, it returns the error and shows me that they are required...is that correct Quote Link to comment https://forums.phpfreaks.com/topic/152902-there-must-be-a-better-wayforms/#findComment-803084 Share on other sites More sharing options...
mosey22 Posted April 7, 2009 Share Posted April 7, 2009 See www.php.net/strip_tags for a description of what that is doing, presumably the test data you gave it was completely stripped, so it returned an empty string and your form validating logic then said, oh, empty string, the field is required. See also www.php.net/htmlspecialchars, which will protect you from this particular trick without wiping out data users submit, in case anyone was compelled to put a < > ' " symbol in the form. I haven't looked through your code completely, but if you're just emailing the posted data you can simply apply htmlspecialchars when displaying form data back to the user only, ie <input type="text" name="something" value="<?php echo( htmlspecialchars($fsomething) ) ?>"> If you apply it immediately, ($fsomething = htmlspecialchars($_POST['something'])) you'd get the html entities in the email that was sent too, which isn't what you want unless you're sending html-formatted email... Quote Link to comment https://forums.phpfreaks.com/topic/152902-there-must-be-a-better-wayforms/#findComment-803120 Share on other sites More sharing options...
tefuzz Posted April 7, 2009 Author Share Posted April 7, 2009 See www.php.net/strip_tags for a description of what that is doing, presumably the test data you gave it was completely stripped, so it returned an empty string and your form validating logic then said, oh, empty string, the field is required. See also www.php.net/htmlspecialchars, which will protect you from this particular trick without wiping out data users submit, in case anyone was compelled to put a < > ' " symbol in the form. I haven't looked through your code completely, but if you're just emailing the posted data you can simply apply htmlspecialchars when displaying form data back to the user only, ie <input type="text" name="something" value="<?php echo( htmlspecialchars($fsomething) ) ?>"> If you apply it immediately, ($fsomething = htmlspecialchars($_POST['something'])) you'd get the html entities in the email that was sent too, which isn't what you want unless you're sending html-formatted email... before changing it I went to php.net and checked both mysql_real_escape_string, and strip_tags. since i'm not insterting anything into a database (yet) I went with strip_tags. I guess I should have clarified more. if I insert say < or > into the name or telephone number fields, it returns that they are required. The email field works great, accepting the @ and the . Should it be clearing the entire string? I do not want HTML to be allowed in the email, since it is just a simple contact form. While looking at php.net I found a link to an xss test site with some code to enter in the fields. I used this one: ';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//\";alert(String.fromCharCode(88,83,83))//--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT> doesn't return an error, it returns that the email was sent (when all the other fields were valid) Is this because I allowed the ' to be in the string? I guess the rare occasion where someone has an ' in their name, they will just have to deal with it? Quote Link to comment https://forums.phpfreaks.com/topic/152902-there-must-be-a-better-wayforms/#findComment-803325 Share on other sites More sharing options...
tefuzz Posted April 8, 2009 Author Share Posted April 8, 2009 umm, maybe something like this may be effective. <?php $fields = array('Full Name' => 'name', 'Email Address' => 'email', 'Telephone' => 'phone'); //list of all fields if(!preg_match('/^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\@([a-z0-9])' . '(([a-z0-9-])*([a-z0-9]))+' . '(\.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$/i', $femail)){ $errors['email'] = "Invalid Email Address"; } $required = array('name', 'email');//array of required fields foreach($required as $name){ if($_POST[$name] <= ''){ $errors[$name] = "$field cannot be left empty."; } } if(count($errors)==0){ //go on with code } else { //If there is erros echo "<span style='color:red;'>\n"; foreach($errors as $error){ echo "<li>$error</li>\n"; } echo "</span>\n<form method='post'>"; echo "<table>"; foreach($fields as $field => $name){ if(is_numeric($field)){ $field = $name; } echo '<tr> <td width="150"> <label>'.$field.'</label></td> <td width="250"><input name="'.$name.'" type="text" id="'.$name.'" tabindex="1" dir="ltr" lang="en" maxlength="65" value="'.$_POST[$name].'"/>'; if(isset($errors[$name])){ echo $errors[$name]; } echo '</td> </tr> <tr>' ; } echo "</table>"; echo "<input type='submit'>"; echo "</form>"; } ?> Good luck, I'm signing out for the day. Just got to read this now...I believe I see exactly what you mean, and it's exactly what I was looking for. Now, to put it into action and make sure I understand it correctly. Quote Link to comment https://forums.phpfreaks.com/topic/152902-there-must-be-a-better-wayforms/#findComment-804385 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.