• Skip to main content
  • Skip to primary sidebar
  • Skip to footer

Matt Doyle | Elated Communications

Web and WordPress Development

  • About Me
  • Blog
    • Design & Multimedia
      • Photoshop
      • Paint Shop Pro
      • Video & Audio
    • Online Marketing
      • E-Commerce
      • Social Media
    • Running a Website
      • WordPress
      • Apache
      • UNIX and Linux
      • Using FTP
    • Web Development
      • HTML
      • CSS
      • JavaScript
      • PHP
      • Perl and CGI Scripting
  • Portfolio
  • Contact Me
  • Hire Me
Home / Blog / Web Development / Perl and CGI Scripting / Form Validation with Perl and CGI

Form Validation with Perl and CGI

12 June 2003 / 13 Comments

In this tutorial we’re going to write a CGI script that checks whether a form has been filled out correctly. Along the way, you’ll also learn about the concepts of reentrant forms and Perl subroutines. Read on!

Why use form validation?

Form validation prevents visitors to your site from accidentally sending you forms with missing or incorrect data. This can save you (and them) a lot of time and trouble!

It’s possible to do form validation using JavaScript (see our Form validation with JavaScript tutorial). JavaScript validation is nice and quick because there’s no round-trip to the server; however Perl validation is more secure and reliable, because it will always work even if the browser has JavaScript disabled, or if the user has managed to “hack” the JavaScript validation.

Reentrant forms

If you’ve followed our Writing a simple form mailer tutorial, you’ll know how to write a simple Perl form handler that uses a static HTML page to display the form. In this tutorial, we’re going to go one step better, and create our HTML form using the Perl script itself!

By doing this, we can re-display the form, along with any data entered by the user and an error message, if the user fills in the form incorrectly. This makes the form handling nice and friendly for the visitor.

This technique is often referred to as creating a reentrant form.

The form display subroutine

In order to create our reentrant form, we’re going to write a subroutine to display the form.

Subroutines, like functions in JavaScript, give you an easy way to run a common function more than once in your script. Once you place your code within a subroutine block, you can run that code as often as you like, from anywhere in the script. What’s more, you can pass parameters into the subroutine, and make it do different things depending on those parameters.

In our example, we’re going to create a subroutine that displays the HTML form. We’ll be calling this subroutine in two ways: firstly, when the blank form is first displayed to the visitor; and secondly, when we need to redisplay the form (including the visitor’s data and any error message) in the event of the user sending us an incorrect form.

To do this, we need to pass any form field values that the user has sent us, and the error message, into the subroutine.

Our form will contain the following fields:

  • “Your Name” (text box)
  • “Your Sex” (radio button)
  • “Your Age” (drop-down list)

Here is our form display subroutine in full:


sub display_form
{
    my $error_message = shift;
    my $your_name = shift;
    my $your_sex = shift;
    my $your_age = shift;

    # Remove any potentially malicious HTML tags
    $your_name =~ s/<([^>]|\n)*>//g;

    # Build "selected" HTML for the "Your Sex" radio buttons
    my $your_sex_f_sel = $your_sex eq "f" ? " checked" : "";
    my $your_sex_m_sel = $your_sex eq "m" ? " checked" : "";

    # Build "selected" HTML for the "Your Age" drop-down list
    my $your_age_html = "";
    my @your_age_opts = ("Please select","Under 18","18-35","35-55","Over 55");

    foreach my $your_age_option ( @your_age_opts )
    {
        $your_age_html .= "<option value=\"$your_age_option\"";
        $your_age_html .= " selected" if ( $your_age_option eq $your_age );
        $your_age_html .= ">$your_age_option</option>";
    }

    # Display the form
    print <<END_HTML;
    <html>
    <head><title>Form Validation</title></head>
    <body>

    <form action="form_validation.cgi" method="post">
    <input type="hidden" name="submit" value="Submit">

    <p>$error_message</p>

    <p>Your Name:<br>
    <input type="text" name="your_name" value="$your_name">
    </p>

    <p>Your Sex:<br>
    <input type="radio" name="your_sex" value="f"$your_sex_f_sel>Female
    <input type="radio" name="your_sex" value="m"$your_sex_m_sel>Male
    </p>

    <p>Your Age:<br>
    <select name="your_age">$your_age_html</select>
    </p>

    <input type="submit" name="submit" value="Submit">

    </form>

    </body></html>
END_HTML

}

The first four lines use Perl’s shift function to retrieve the parameters passed into it (if any). We then dynamically create and display the HTML for the form, pre-filling the form fields with any values that the user has already entered (passed via the parameters). The subroutine will also display any error message (again, passed as a parameter) at the top of the form.

Note that we’re using a regular expression to filter the $your_name variable and remove any HTML tags before we display it in our form. This is a good idea as it will limit the risk of form hacking and cross-site-scripting attacks.

When writing real-world Web applications and scripts, always filter any data that the script receives from an untrusted source. This includes any data from form posts, GET variables in query strings, uploaded files and anything else that might have been created by someone, or something, you don’t control.

The form contains a submit button called submit – our script can later use this field to determine if the form has been submitted yet or not. For backup, the same field is defined as a hidden field, in case the user just presses the Enter key rather than clicking on the “Submit” button.

The form validation subroutine

We’ll now write the subroutine that checks the form fields entered by the user. If all the fields have been filled in correctly, we will return a success value (in this case, 1). If any fields are missing, we will call our reentrant form display subroutine above, passing in any fields that the user has entered, along with the error message, as parameters to the subroutine. We then return a failure value of 0.


sub validate_form
{
    my $your_name = $query->param("your_name");
    my $your_sex = $query->param("your_sex");
    my $your_age = $query->param("your_age");

    my $error_message = "";

    $error_message .= "Please enter your name<br/>" if ( !$your_name );
    $error_message .= "Please specify your sex<br/>" if ( !$your_sex );
    $error_message .= "Please specify your age<br/>" if
    ( $your_age eq "Please select" );

    if ( $error_message )
    {
        # Errors with the form - redisplay it and return failure
        display_form ( $error_message, $your_name, $your_sex, $your_age );
        return 0;
    }
    else
    {
        # Form OK - return success
        return 1;
    }
}

We’ve used Perl’s string concatenation operator (.=) to append any error messages to the $error_message string. We can then test this string at the end of our checks to determine if it’s empty or not. If it isn’t empty, then we know there were errors, and we can redisplay the pre-filled form along with the error message, and return the failure code.

We can test if a form field is empty (i.e. the user hasn’t entered anything) by using the not (!) operator. This returns a true value if the tested variable is empty. For example:


    $error_message .= "Please enter your name</br>" if ( !$your_name );

Putting it all together

We’ll now write the rest of the script, including the decision-making logic. Here it is:


#!/usr/bin/perl

use CGI;

# Create the CGI object
my $query = new CGI;

# Output the HTTP header
print $query->header ( );

# Process form if submitted; otherwise display it
if ( $query->param("submit") )
{
    process_form ( );
}
else
{
    display_form ( );
}

sub process_form
{
    if ( validate_form ( ) )
    {
        print <<END_HTML;
        <html><head><title>Thank You</title></head>
        <body>
        Thank you - your form was submitted correctly!
        </body></html>
END_HTML
    }
}

This code just initialises the CGI query object, displays the HTTP header, and then calls either the process_form() subroutine or the display_form() subroutine, depending on whether the form has been submitted or not. (We test the value of the form field submit to determine if the form has been submitted – if the field is non-empty then the test returns true.)

The process_form() subroutine calls validate_form(), then simply displays a thank-you message if the form was filled in correctly. In a “real-world” application you would do all your actual form processing here (sending an email, adding a record to a database table, etc).

The finished script

You can view the whole script here, and see the script in action here. Try submitting the form without filling in all the fields, and see the results!

Filed Under: Perl and CGI Scripting Tagged With: cgi-bin, form checking, server-side, validator, web development

Reader Interactions

Comments

  1. perlprofesional says

    16 November 2009 at 12:19 pm

    The example script which has given here is truely wonderful and much helpful for me. Thanks a lot.

    Reply
  2. matt says

    17 November 2009 at 12:28 am

    You’re welcome, perlprofesional – I’m glad it helped! πŸ™‚
    Matt

    Reply
  3. crly says

    12 April 2010 at 1:40 am

    Hi, I’m new to perl scripting, but the article was great, so I followed along and think I have most of my script under control, but seem to be getting errors related to the radio buttons in the ‘display_form’ function.

    My browser returns:
    “Premature end of script headers …”

    So in my Shell window when doing “perl -w” on my script I get:
    Use of unitialized value in string eq at myscript.cgi line …

    I think this is what it’s referring to:

    
    # Build selected HTML for the support radio buttons
    $support_rspca_sel = $support eq "RSPCA" ? " checked" : "";
    $support_awl_sel = $support eq "AWL" ? " checked" : "";
    
    

    Then I refer to that later in my form:

    
    <label><input type="radio" name="support" value="AWL"$support_awl_sel>AWL (Qld)</label>
    <br>
    <label><input type="radio" name="support" value="RSPCA"$support_rspca_sel>RSPCA (Qld)</label>
    
    

    My syntax check came back with an OK.
    What am I missing? Thanks for your time on this. Much appreciated.
    Carly

    Reply
  4. matt says

    16 April 2010 at 3:02 am

    Hi Carly,

    Actually the “uninitialized value” error is probably because you turned warnings on with -w. It may not be what’s causing your 500 server error (unless you’re also using #!/usr/bin/perl -w at the top of your script?).

    The best bet is probably to use the CGI::Carp module to display errors in the browser, rather than the generic 500 error:

    http://perldoc.perl.org/CGI/Carp.html

    In other words, add this below the “use CGI;” line in your script:

    use CGI::Carp qw(fatalsToBrowser);
    

    You’ll then see the exact error message in your browser when you run the script.

    Does that help?

    Reply
  5. crly says

    18 April 2010 at 11:38 pm

    Thanks Matt. It’s running now. I’m still having a few issues but I’m just removing the code and putting pieces back in to figure it out. Just taking it one thing at a time πŸ™‚ Will get there eventually!
    Carly

    Reply
  6. matt says

    20 April 2010 at 9:31 pm

    No probs Carly. Feel free to ask for more help if you need it!

    Reply
  7. karan says

    2 August 2010 at 5:51 pm

    Hi, i need some help regarding making HTML forms with perl scripting for the server side. As I am using oracle database for my project, I know how to make the connectiong but i need to know a few things..

    1. If am using Perl, is it better to embed it in HTML forms or Is it better to make HTML forms and then post them to Perl and use Perl for server scripting?

    2. I need to insert a lot of data into the database, so, the HTML forms will be quite lengthy, so in your opinion which option is better and where can i find examples for the chosen method..

    Please Help!!! your help will be really appreciated.

    Reply
  8. matt says

    2 August 2010 at 6:23 pm

    @karan: Your questions don’t make a lot of sense. Are you talking about form validation, or form processing?

    You can’t normally embed Perl within HTML unless you’re using a library such as HTML::Embperl.

    Reply
  9. karan says

    2 August 2010 at 8:13 pm

    I am not talking about form validation here. sorry the question got posted under the wrong topic. I need to simply create HTML forms which will insert the data into database.
    for inserting it into database i am using perl (coz seemingly only tat works on the university’s server for oracle connection)

    my question is how can i use perl as an interface between html and oracle. are there any examples? I am relatively new to perl, hence jumbled questions.

    Reply
  10. matt says

    2 August 2010 at 8:25 pm

    @karan: The script at http://www.elated.com/articles/form-validation-with-perl-and-cgi/ should actually give you a good starting point. Instead of displaying the entered form data in the page, you’d instead insert the data into your Oracle database using SQL INSERT statements. You’ll probably want to use DBI for this – here are some good articles on the topic:

    http://www.dba-oracle.com/t_dbi_interface1.htm

    Reply
  11. dhinawithlove says

    18 April 2011 at 8:46 am

    hi… the script is great and was a good starting point for form validation… i am facing difficulties in reading <textarea> input… i am able to grab only the first line in the text area… can u please help…

    thanks
    dhina

    Reply
  12. dhinawithlove says

    18 April 2011 at 9:15 am

    hello sir…
    sorry… i fixed the script.. mistake was mine… i just read the other related posts and fixed the error! πŸ™‚

    thanks

    Reply
  13. matt says

    20 April 2011 at 2:18 am

    @dhina: No problem – I’m glad you got your script working. πŸ™‚

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

To include a block of code in your comment, surround it with <pre> ... </pre> tags. You can include smaller code snippets inside some normal text by surrounding them with <code> ... </code> tags.

Allowed tags in comments: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre> .

Primary Sidebar

Hire Matt!

Matt Doyle headshot

Need a little help with your website? I have over 20 years of web development experience under my belt. Let’s chat!

Matt Doyle - Codeable Expert Certificate

Hire Me Today

Call Me: +61 2 8006 0622

Stay in Touch!

Subscribe to get a quick email whenever I add new articles, free goodies, or special offers. I won’t spam you.

Subscribe

Recent Posts

  • Make a Rotatable 3D Product Boxshot with Three.js
  • Speed Up Your WordPress Website: 11 Simple Steps to a Faster Site
  • Reboot!
  • Wordfence Tutorial: How to Keep Your WordPress Site Safe from Hackers
  • How to Make Awesome-Looking Images for Your Website

Footer

Contact Matt

  • Email Me
  • Call Me: +61 2 8006 0622

Follow Matt

  • E-mail
  • Facebook
  • GitHub
  • LinkedIn
  • Twitter

Copyright © 1996-2023 Elated Communications. All rights reserved.
Affiliate Disclaimer | Privacy Policy | Terms of Use | Service T&C | Credits