Hudzilla.org - the homepage of Paul Hudson
Contents > HTML Forms > Validating input Wish List | Report Bug | About Me ]

7.7.3     Validation in practice: is_string(), is_numeric(), is_float(), is_array(),is_object(), and is_resource()

This is NOT the latest copy of this book; click here for the latest version.

bool is_string ( mixed var)

bool is_numeric ( mixed var)

bool is_float ( mixed var)

bool is_array ( mixed var)

bool is_object ( mixed var)

bool is_resource ( mixed var)

Any sensible site should include server-side validation of variables, simply because they are much harder to hack through, and because they will work no matter what browsers your visitors are using. The question is: how much client-side validation should be used?

In practice I server-validate everything, and client-validate as much as is possible. That way I am reducing server load because most people will take the hints from the client-side scripts and get the form right, and I am also keeping user wait times down. If you don't have time for this - after all, coding in JavaScript is not much fun - then you should at least client-validate variables that are of particular importance to your script. For example, check email addresses, ID numbers, and the like - it all helps improve your user experience.

When validating data in PHP, I find it easiest to create an array of field names that are required, then make each field in my form an element in a master array - this allows me to check for required fields merely be differencing the two, and also to validate each field by simply looping through the array of submitted value.

Consider this script:

<?php
    
if (isset($_POST['Form'])) {
        
import_request_variables("p", "z");
        
$missingfields = array();
        
$required = array("FName"=>"First Name", "LName"=>"Last Name");

        while (list(
$var, $val) = each($required)) {
            if (isset(
$zForm[$var]) && $zForm[$var] != '') {
                
// check this value further here
            
} else {
                
$missingfields[$var] = $val;
            }
        }

        if (
count($missingfields)) {
            print
"You missed out one or more fields:<BR />";

            while(list(
$var, $val) = each($missingfields)) {
                print
$val . "<BR />";
            }
        } else {
            print
"Form passed!<BR />";
            
var_dump($zForm['Languages']);
            exit;
        }
    }
?>

<FORM METHOD="POST" ACTION="array.php">
First Name: <INPUT TYPE="TEXT" NAME="Form[FName]" /> (required)<BR />
Last Name: <INPUT TYPE="TEXT" NAME="Form[LName]" /> (required) <BR />
Age: <INPUT TYPE="TEXT" NAME="Form[Age]" /><BR /><BR />
Languages known:<BR />
<INPUT TYPE="CHECKBOX" NAME="Form[Languages][]" VALUE="PHP" CHECKED> PHP</INPUT>
para><INPUT TYPE="CHECKBOX" NAME="Form[Languages][]" VALUE="CPP"> C++</INPUT>
<INPUT TYPE="CHECKBOX" NAME="Form[Languages][]" VALUE="Delphi"> Delphi</INPUT>
<INPUT TYPE="CHECKBOX" NAME="Form[Languages][]" VALUE="Java"> Java</INPUT>
<INPUT TYPE="submit" />
</FORM>

First take a look over the HTML part - notice that the NAME attribute for each element is Form[xxxx], which means PHP will end up with one variable holding an array containing each HTML element. Particularly of interest is Form[Languages], which has an empty set of square brackets after it - this is so that $Form['Languages'] will be an array of the selected languages.

The PHP code to handle the form is only a little more complicated than the HTML, and is only executed if $_POST['Form'] has been set - that is, if the form has been submitted. The first thing I do is to use import_request_variables() to make all POST variables ("p") into regular variables, preceded with the letter "z", which will create the variable $zForm containing our user input.

The next step is to create an array of field names that are required fields - the reason it is a two-dimensional array is because the first dimension stores the field name (e.g. Fname), and the second dimension stores the textual name of the field (e.g. First Name). Testing for required fields being set is as simple as looping through the array of required fields, making sure each field is set in user input and also, crucially, making sure that the field has a non-blank value.

Each required value that is missing gets an entry in the $missingfields array, which is printed out at the end if there are any fields missing. The reason $missingfields is declared as an empty array just after import_request_variables() is because PHP will flag an error if we call count() on $missingfields when it hasn't been set, which would be the case if no missing fields were found.

One the form passes, there is a call to var_dump() in there so that you can see how the array-within-array mechanism works.

That script performs fairly basic validation - the comment "// check this value further here" is where you can really get into the nitty-gritty, because just verifying that a variable exists and is set is not really enough to get you by. At this point you need to call in the cavalry of type checking, which, in PHP terms, is the set of functions is_string(), is_numeric(), is_float(), is_array(), and is_object().

Each of these functions take just one parameter, a variable of their namesake, and return true if that variable is of the appropriate type. For example, is_numeric() will return true if the variable passed to it is a number, and is_object() will return true if its variable is an object. There is one other function of this type that works the same way but is useless for validation, and that is is_resource() - it's mentioned here for the sake of completeness.

Once you have verified that you have each of your required variables, that they are not empty, and that they are of the type you were expecting, you can go on to do more complicated checks. Are the integer values in the range you would expect? Do the string values have enough characters? Do the arrays have enough elements? Check, check, and check again, as it's better to validate your data early and issue an error as opposed to letting subtly bad input into your system.

Author's Note: There is a function confusingly similar to is_numeric(), called is_int(). This returns true if the variable passed in is an integer, which may sound similar to is_numeric(). However, data passed in through a form, even if numeric in content, is of type string, which means that is_int() will fail. Is_numeric(), on the other hand, returns true if the variable is a number or if it is a string containing a number also. This same problem applies to is_float(), as floating-point values set from user input are typed as strings.





<< 7.7.2 Server-side validation   7.7.4 Advanced variable validation using CTYPE >>
Table of Contents
Want to see this stuff in print? PHP in a Nutshell takes the core topics covered here, adds in thousands of edits from the editorial team and myself, and combines them to make an unbeatable reference for PHP programmers at all levels.



My latest book has hundreds more tips on how to use PHP, Apache, and MySQL, plus Perl, Python, shell scripts, performance tuning, and more!



Top-right shadow
 
Bottom-left shadow Bottom shadow

Comments from other readers
daniel - 05 Dec 2008

Hack 127.0.0.1 if you dare.

A PHP User - 05 Dec 2008

its not working.

A PHP User - 05 Dec 2008

its working.

A PHP User - 05 Dec 2008

This code doesnt work. why are you cheating people

ptrpan - 05 Dec 2008

for a nice regex tool go to http://www.cuneytyilmaz.com/prog/jrx/jrx.nongecko.html

danflory@sbcglobal - 05 Dec 2008

For validation nothing is better than regular expressions. See Chapter 4.8 In particular don't forget to use the regular expression coach mentioned in 4.8.7.

I would add also "Regex buddy" that will take your regular expression and format it for PHP according to serveral usage needs. - not free but It has saved me hours upon hours.

Regular expressions are handy little buggers. And always a little tricky to get right.

mansur_agasar@yahoo.co.in - 05 Dec 2008

how to display the database reports in php

Kevin - 05 Dec 2008

Good job!



Add comment
Please note that by posting a comment here you are committing it to the public domain. This is important so that others can make use of your code themselves, and also so that I can incorporate helpful notes directly into the main text. Comments are limited to 2000 characters in length.

If you are reporting an error in the content, please tell me directly.

Your name/email address:
Your comment:
 
Now, in order to verify that you're a real person, please answer this simple question: what is nine plus six?
The answer is:
(please write in
numbers, eg 19)


Top-right shadow
 
Bottom-left shadow Bottom shadow