Welcome to Dream.In.Code
Getting Help is Easy!

Join 109,296 Programmers for FREE! Ask your question and get quick answers from experts. There are 1,226 online right now! We've got more than 500 tutorials and 2,000 snippets. Join and find out why Dream.In.Code is the #1 programming help community on the internet! Registration is fast and FREE... Join Now!



Validating forms with PHP

 
Reply to this topicStart new topic

> Validating forms with PHP, Validating an input and displaying error messages based on what's

spearfish
Group Icon



post 15 Mar, 2008 - 03:41 AM
Post #1


Hey guys---

This is my first shot at a tutorial, so it'll probably be a rough ride. Try to bear with me, and correct me when needed. It's also pretty late, so forgive any grammatical errors / typos (although I would appreciate you pointing them out). I have tested this script, it works. cool.gif

In this tutorial I'll show you how to validate forms using PHP. Sure, you can validate forms using JavaScript. It's a whole lot faster. But what happens if the use simply turns JavaScript off? In that case, maybe you need to make the submit button disabled, unless the form checks out alright. But then what if the user has no JavaScript support at all? And, what if you hit a smart bugger who simply copies your HTML form, minus the JavaScript (see "formhack.html").

JavaScript is still a nice validation tool, especially for giving people on-the-fly feedback. But if you rely solely on it, you're screwed. I'll show you how to add the PHP part:

What you need:
  • A PHP enabled web server
  • Patience
~~~

Let's suppose that this page is receiving information via POST from a form. What we want to do is check to see if it meets various requirements, and then telling the user exactly what's wrong. If there's one thing wrong with it, they see one error message. Thirty things wrong? Thirty error messages.

CODE

<?php
$information = $_POST['formdata'];


There are several things we can do to validate $information, all of which use PHP's ereg function. Bene notate that this is a case sensitive function. For most validation, you probably want case insensitivity, unless you're going to be a real jerk and stop them for not capitalizing their name. Thus, I will be using the eregi function throughout the tutorial, a duplicate of ereg except with case insensitivity. I'll also cast any boolean values to integers. You don't have to, I just dislike dealing with booleans.

The basic format for the custom - error - validation system is to pass the string in question through several tests, what I like to call the gauntlet. Then, if it passes every test, code executes. Otherwise, the code digs deeper, and using a series of "if" statements (the crucial part here is to use simply if ( ) { rather than else if ( ) {) displays what all is wrong with the information.
~~~

I'll first go through as if $information is containing a string that should contain numbers and letters, for something like a username, or an address. Then I'll go into the specific examples of phone numbers and email addresses. I won't be covering captchas, but there's a snippet here.

First, let's make sure that $information only contains numbers, letters, or any other characters you want to throw in (I mean, if you like people creating usernames such as "%@$7 #(h)".... ). What we need to do is search for any character that isn't on the list of accepted characters. If we simply search for something on the list, the aforementioned repugnant username passes, because it does contain an "h".
CODE

$validate1 = eregi('[^a-z0-9]', $information);
$validate1 = (int)$validate1;


This function's syntax is eregi('string to search for', 'string to search');. What we've done here is assigned a character set. Instead of searching for "a" or "bat", it's searching for anything that's a-z or 0-9 (alphanumeric).

By placing a "^" at the front of the character set, the entire class is negated - now it's looking for something other than what's in that set. Just what we need. A tip: if you want to allow underscores (for, say, usernames), change[^a-z0-9] to [^a-z0-9_]. Similarly, add a "$" to there if you want people to be able to have $ in the form field.
~~~

Next we'll be looking at the words inside the string. Again, falling back to the username example, you don't want "iamashithead" interacting with the other users. To block certain words, try this:
CODE

$validate2 = eregi('naughty|word', $information);
$validate2 = (int)$validate2;


In this example, the function returns true if it finds either 'naughty' or 'word'. Arguably one of the most fun parts of a website is this step: rattling off every cuss word you can and putting them into this list.
~~~

Suppose you're validating an address. Although you probably can only be sure about the validity of the address is by mailing something there, you can make sure it's in the right format.

When searching for a character class, you can use quantifiers to specify the quantity of what's needed. So let's say that to pass our gauntlet, an address needs to have a number in front, followed by at least four numbers.

CODE

$validate3 = eregi('[0-9] [a-z]{4,}', $information
$validate3 = (int)$validate3;


The {4,} means that it needs to find something a-z at least four times. {a} means exactly "a" times; {a,b} means at least "a" times, but no more than "b" times.

You can use quantifiers to validate based on string length, but it's easier to use $validateX = strlen($information);
~~~

Next, let's say that you need to ensure that nobody makes a username starting with "STAFF_". It'd be nice to distinguish site staff from regular users in as many ways as possible, but if I can go to your site and make "STAFF_Spearfish"; "STAFF_yourname" doesn't help at all.

So, you can stop that with an anchor, ^. This is confusing, because it's the same symbol that negates character sets.... but try to keep them straight. Just remember that when it's outside of a character class it's an anchor, like a boat --- because it's always getting thrown overboard. pirate.gif

So, for this example:
CODE

$validate4 = eregi('^(STAFF_)', $information);
$validate4 = (int)$validate4;


The user is perfectly welcome to make "the_staff_is_great"; provided you haven't blocked underscores. Similarly, you can use "$" to indicate that the string being looked for must be at the end of the string to be searched.
~~~

Now, let's put this all together. Additionally, we need the string to be 3-24 characters long to comply with database restrictions.

This may look long and confusing at first, but break it down piece by piece. Ugly code can still lead to an elegant result.

For your testing pleasure, it also includes the form that's posting this information. Throw the file onto a server and have fun!

CODE

<?php
if(isset($_POST['formdata'])) {
$information = $_POST['formdata'];
$validate1 = eregi('[^a-z0-9 ]', $information);
$validate1 = (int)$validate1;
$validate2 = eregi('naughty|word', $information);
$validate2 = (int)$validate2;
$validate3 = eregi('[0-9] [a-z]{4,}', $information);
$validate3 = (int)$validate3;
$validate4 = eregi('^(STAFF_)', $information);
$validate4 = (int)$validate4;
$validate5 = strlen($information);
if ($validate1 == 0 && $validate2 == 0 && $validate3 == 1 && $validate4 == 0 && $validate5 > 2 && $validate5 < 25) {
echo "Success!  \"<i>$information</i>\" is a valid string";
// Coding goes here.... inserting to a database?  Setting cookies?  Who knows.  But it passed the gauntlet
} else {
echo "Sorry, \"<i>$information</i>\" failed.  Here's why: <ul>";
   if ($validate1 == 1) {
echo "<li>Your string contains invalid characters.  It can only contain letters, numbers, and spaces.</li>";
} if ($validate2 == 1) {
echo "<li>Egad!  Don't talk like that! (Hotwords: 'naughty' and 'word')</li>";
} if ($validate3 == 0) {
echo "<li>That doesn't look like a valid address to me! (Must be a number, follwed by a space, then at least four letters)</li>";
} if ($validate4 == 1) {
echo "<li>Sorry, but all accounts starting with <b>STAFF_</b> have been reserved.</li>";
} if ($validate5 < 3) {
echo "<li>\"<i>$information\"</i> is too short (only $validate5 characters)!  It needs to be at least 3.</li>";
} if ($validate5 > 24) {
echo "<li>\"<i>$information</i>\" is too long (a whole $validate5 characters)!  It can't be more than 24.</li>";
}
echo "</ul>";  }
}
?>
<br />
<form action='validator.php' method='post'>
<input type='text' name='formdata' />
<input type='submit' value='Test that string!' />
</form>
<br />


Phew! Let me point out a few things:
If it passes the validation --- all of the tests turn out the way we want them to --- then it says so, and you can place code to happen. If it failed, it says so, and starts an unorganized list, and runs through the checklist of things that could have gone wrong, displaying each error as a list item in an unorganized list.
~~~

Now, let's focus on the two other things: Phone numbers and Email addresses. Phone numbers are easy using quantifiers....
CODE

$validate6 = eregi('[0-9]{3}-[0-9]{3}-[0-9]{4}', $information);


That searches for a phone number in 123-456-7890 format.

For email addresses, try this:
CODE

$validate7 = eregi('[a-z0-9'][@]{1}[a-z0-9][.][a-z.]{2,}', $information);


This isn't a sure-fire validator for email addresses, but it does stop the outrageous strings. Test yourself by trying to build an email validator that works 100% for syntax checking (for example, "ab@9.coa.awe.wer" passes this validation, while "notarealemail@a.b" fails).
~~~

I appreciate your feedback, and would love to hear about things I should have included, things that weren't explained well, or things that I got wrong (gasp!).

If this is the first time you've seen this stuff and you're still hanging on, congratulations. I was overwhelmed when I first saw it. Be sure to post below if you need more detail or more examples.

Spearfish
~~~

Pictures:
I passed validation!
Attached Image

Oh no, I failed! crazy.gif
Attached Image

The finished product icon_up.gif
Attached Image

Download the validator file:
Attached File  validator.php ( 1.73k ) Number of downloads: 120


Download formhack.html (you aren't realy "hacking" a site --- it's just showing how easily JavaScript validation can be bypassed)
Attached File  formhack.html ( 728bytes ) Number of downloads: 101


This post has been edited by spearfish: 18 Mar, 2008 - 07:16 AM
Go to the top of the page
+Quote Post


Register to Make This Ad Go Away!

spearfish
Group Icon



post 25 Mar, 2008 - 07:35 PM
Post #2
I'd just like to point out something interesting that came up (and couldn't find the edit button stupid.gif). Let's say you need to find two numbers in the password, to be sure it's secure. You'd do something like this:

CODE

$passval1 = eregi("[0-9].*[0-9]", $pass);


The period means that anything can take that place. The star is a fancy way of saying {0,}

You also might find useful:
? = {0,1}; meaning zero or one times
+ = {1,}; meaning at least once
Go to the top of the page
+Quote Post

chrisman
Group Icon



post 25 Mar, 2008 - 08:07 PM
Post #3
Hehe. Thanks for the appending.

BTW: <ul> starts and unORDERED list, not an unORGANIZED one. Picky, picky me. dry.gif
Go to the top of the page
+Quote Post

spearfish
Group Icon



post 26 Mar, 2008 - 10:40 AM
Post #4
Fine, be like that. You're right though - I looked it up.

I'm excited, this page just got indexed by Google - that's why there's so many views all of the sudden.

This post has been edited by spearfish: 26 Mar, 2008 - 01:19 PM
Go to the top of the page
+Quote Post

Chopster
*



post 19 Jul, 2008 - 07:05 AM
Post #5
Great tutorial man, i have been struggling with this for a while, but now it's alot clearer, applying to my project now

thanks again icon_up.gif icon_up.gif

Edit: Got it working fine, few little niggles converting it to my project, but its all good now, cheers again!

This post has been edited by Chopster: 19 Jul, 2008 - 07:56 AM
Go to the top of the page
+Quote Post


Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 

Lo-Fi Version Time is now: 9/6/08 09:32AM

Live Help!

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

Bye Bye Ads

Free DIC T-Shirt

T-Shirt Example

Related Sites

Monthly Drawing

Thumb Drive

Partners

Top Contributors

Top 10 Kudos This Month