[logo] CGI.pm - a Perl5 CGI Library
Version 2.39, 3/24/98, L. Stein
Abstract
This perl 5 library uses objects to create Web fill-out forms on the fly and
to parse their contents. It provides a simple interface for parsing and
interpreting query strings passed to CGI scripts. However, it also offers a
rich set of functions for creating fill-out forms. Instead of remembering
the syntax for HTML form elements, you just make a series of perl function
calls. An important fringe benefit of this is that the value of the previous
query is used to initialize the form, so that the state of the form is
preserved from invocation to invocation.
Everything is done through a ``CGI'' object. When you create one of these
objects it examines the environment for a query string, parses it, and
stores the results. You can then ask the CGI object to return or modify the
query values. CGI objects handle POST and GET methods correctly, and
correctly distinguish between scripts called from documents and
form-based documents. In fact you can debug your script from the command
line without worrying about setting up environment variables.
A script to create a fill-out form that remembers its state each time it's
invoked is very easy to write with CGI.pm:
#!/usr/local/bin/perl
use CGI qw(:standard);
print header;
print start_html('A Simple Example'),
h1('A Simple Example'),
start_form,
"What's your name? ",textfield('name'),
p,
"What's the combination?",
p,
checkbox_group(-name=>'words',
-values=>['eenie','meenie','minie','moe'],
-defaults=>['eenie','minie']),
p,
"What's your favorite color? ",
popup_menu(-name=>'color',
-values=>['red','green','blue','chartreuse']),
p,
submit,
end_form,
hr;
if (param()) {
print
"Your name is",em(param('name')),
p,
"The keywords are: ",em(join(", ",param('words'))),
p,
"Your favorite color is ",em(param('color')),
hr;
}
print a({href=>'../cgi_docs.html'},'Go to the documentation');
Select this link to try the script
More scripting examples
Contents
* Downloading & Installation
* Creating a new CGI query object
* Saving the state of the form
* CGI Functions that Take Multiple Arguments
* Creating the HTTP header
* HTML shortcuts
* Creating forms
* Importing CGI methods
* Debugging
* HTTP session variables
* Netscape Cookies
* Support for Netscape frames
* Support for JavaScript
* Limited Support for Cascading Style Sheets
* Using NPH Scripts
* Advanced techniques
* Subclassing CGI.pm
* Using CGI.pm with mod_perl and FastCGI
* Migrating from cgi-lib.pl
* Using the File Upload Feature
* Avoiding Denial of Service Attacks
* Using CGI.pm on non-Unix Platforms
* The Relationship of CGI.pm to the CGI::* Modules
* Distribution information
* CGI-perl mailing list
* What's new in version 2.39?
------------------------------------------------------------------------
Downloading & Installation
* Download 2.39 (gzip tar archive)
* Download 2.39 (pkzip archive)
* Download 2.37 beta package (Macintosh stuffit archive)
* Download just the CGI module (uncompressed)
This package requires perl 5.003 patch level 7 or higher. Earlier versions
of Perl may work, but CGI.pm has not been tested with them. If you're really
stuck, edit the source code to remove the line that says "require 5.00307",
but don't be surprised if you run into problems.
If you are using a Unix system, you should have perl do the installation for
you. Move to the directory containing CGI.pm and type the following
commands:
% perl Makefile.PL
% make
% make install
You may need to be root to do the last step.
This will create two new files in your Perl library. CGI.pm is the main
library file. Carp.pm (in the subdirectory "CGI") contains some optional
utility routines for writing nicely formatted error messages into your
server logs. See the Carp.pm man page for more details.
If you get error messages when you try to install, then you are either:
1. Running a Windows NT port of Perl (or another port) that doesn't have
make or the MakeMaker program built into it.
2. Have an old version of Perl. Upgrade to 5.003_7 or higher.
In the former case don't panic. Here's a recipe that will work (commands are
given in MS-DOS/Windows form):
> cd CGI.pm-2.38
> copy CGI.pm C:\Perl\lib
> mkdir C:\Perl\lib\CGI
> copy CGI\*.pm C:\Perl\lib\CGI
Modify this if your Perl library has a different location.
If you do not have sufficient privileges to install into
/usr/local/lib/perl5, you can still use CGI.pm. Modify the installation
recipe as follows:
% perl Makefile.PL INSTALLDIRS=site INSTALLSITELIB=/home/your/private/dir
% make
% make install
Replace /home/your/private/dir with the full path to the directory you want
the library placed in. Now preface your CGI scripts with a preamble
something like the following:
use lib '/home/your/private/dir';
use CGI;
Be sure to replace /home/your/private/dir with the true location of CGI.pm.
Notes on using CGI.pm in NT and other non-Unix platforms
------------------------------------------------------------------------
Creating a new CGI object
The most basic use of CGI.pm is to get at the query parameters submitted to
your script. To create a new CGI object that contains the parameters passed
to your script, put the following at the top of your perl CGI programs:
use CGI;
$query = new CGI;
In the object-oriented world of Perl 5, this code calls the new() method of
the CGI class and stores a new CGI object into the variable named $query.
The new() method does all the dirty work of parsing the script parameters
and environment variables and stores its results in the new object. You'll
now make method calls with this object to get at the parameters, generate
form elements, and do other useful things.
An alternative form of the new() method allows you to read script parameters
from a previously-opened file handle:
$query = new CGI(FILEHANDLE)
The filehandle can contain a URL-encoded query string, or can be a series of
newline delimited TAG=VALUE pairs. This is compatible with the save()
method. This lets you save the state of a CGI script to a file and reload it
later. It's also possible to save the contents of several query objects to
the same file, either within a single script or over a period of time. You
can then reload the multiple records into an array of query objects with
something like this:
open (IN,"test.in") || die;
while (!eof(IN)) {
my $q = new CGI(IN);
push(@queries,$q);
}
You can make simple databases this way, or create a guestbook. If you're a
Perl purist, you can pass a reference to the filehandle glob instead of the
filehandle name. This is the "official" way to pass filehandles in Perl5:
my $q = new CGI(\*IN);
(If you don't know what I'm talking about, then you're not a Perl purist and
you needn't worry about it.)
If you are using the function-oriented interface and want to initialize CGI
state from a file handle, the way to do this is with restore_parameters().
This will (re)initialize the default CGI object from the indicated file
handle.
open (IN,"test.in") || die;
restore_parameters(IN);
close IN;
You can initialize a CGI object from an associative-array reference. Values
can be either single- or multivalued:
$query = new CGI({'dinosaur'=>'barney',
'song'=>'I love you',
'friends'=>[qw/Jessica George Nancy/]});
You can initialize a CGI object by passing a URL-style query string to the
new() method like this:
$query = new CGI('dinosaur=barney&color=purple');
Or you can clone a CGI object from an existing one. The parameter lists of
the clone will be identical, but other fields, such as autoescaping, are
not:
$old_query = new CGI;
$new_query = new CGI($old_query);
This form also allows you to create a CGI object that is initially empty:
$empty_query = new CGI('');
See advanced techniques for more information.
Fetching A List Of Keywords From The Query
@keywords = $query->keywords
If the script was invoked as the result of an search, the parsed
keywords can be obtained with the keywords() method. This method will return
the keywords as a perl array.
Fetching The Names Of All The Parameters Passed To Your Script
@names = $query->param
If the script was invoked with a parameter list (e.g.
"name1=value1&name2=value2&name3=value3"), the param() method will return
the parameter names as a list. For backwards compatability, this method will
work even if the script was invoked as an script: in this case
there will be a single parameter name returned named 'keywords'.
Fetching The Value(s) Of A Named Parameter
@values = $query->param('foo');
-or-
$value = $query->param('foo');
Pass the param() method a single argument to fetch the value of the named
parameter. If the parameter is multivalued (e.g. from multiple selections in
a scrolling list), you can ask to receive an array. Otherwise the method
will return a single value.
As of version 1.50 of this library, the array of parameter names returned
will be in the same order in which the browser sent them. Although this is
not guaranteed to be identical to the order in which the parameters were
defined in the fill-out form, this is usually the case.
Setting The Value(s) Of A Named Parameter
$query->param('foo','an','array','of','values');
-or-
$query->param(-name=>'foo',-values=>['an','array','of','values']);
This sets the value for the named parameter 'foo' to one or more values.
These values will be used to initialize form elements, if you so desire.
Note that this is the one way to forcibly change the value of a form field
after it has previously been set.
The second example shows an alternative "named parameter" style of function
call that is accepted by most of the CGI methods. See Calling CGI functions
that Take Multiple Arguments for an explanation of this style.
Appending a Parameter
$query->append(-name=>'foo',-values=>['yet','more','values']);
This adds a value or list of values to the named parameter. The values are
appended to the end of the parameter if it already exists. Otherwise the
parameter is created.
Deleting a Named Parameter Entirely
$query->delete('foo');
This deletes a named parameter entirely. This is useful when you want to
reset the value of the parameter so that it isn't passed down between
invocations of the script.
Deleting all Parameters
$query->delete_all();
This deletes all the parameters and leaves you with an empty CGI object.
This may be useful to restore all the defaults produced by the form element
generating methods.
Importing parameters into a namespace
$query->import_names('R');
print "Your name is $R::name\n"
print "Your favorite colors are @R::colors\n";
This imports all parameters into the given name space. For example, if there
were parameters named 'foo1', 'foo2' and 'foo3', after executing
$query->import_names('R'), the variables @R::foo1, $R::foo1, @R::foo2,
$R::foo2, etc. would conveniently spring into existence. Since CGI has no
way of knowing whether you expect a multi- or single-valued parameter, it
creates two variables for each parameter. One is an array, and contains all
the values, and the other is a scalar containing the first member of the
array. Use whichever one is appropriate. For keyword (a+b+c+d) lists, the
variable @R::keywords will be created.
If you don't specify a name space, this method assumes namespace "Q".
An optional second argument to import_names, if present and non-zero, will
delete the contents of the namespace before loading it. This may be useful
for environments like mod_perl in which the script does not exit after
processing a request.
Warning: do not import into namespace 'main'. This represents a major
security risk, as evil people could then use this feature to redefine
central variables such as @INC. CGI.pm will exit with an error if you try to
do this.
Direct Access to the Parameter List
$q->param_fetch('address')->[1] = '1313 Mockingbird Lane';
unshift @{$q->param_fetch(-name=>'address')},'George Munster';
If you need access to the parameter list in a way that isn't covered by the
methods above, you can obtain a direct reference to it by calling the
param_fetch() method with the name of the parameter you want. This will
return an array reference to the named parameters, which you then can
manipulate in any way you like.
You may call param_fetch() with the name of the CGI parameter, or with the
-name argument, which has the same meaning as elsewhere. Table of contents
------------------------------------------------------------------------
Saving the Current State of a Form
Saving the State to a File
$query->save(FILEHANDLE)
This writes the current query out to the file handle of your choice. The
file handle must already be open and be writable, but other than that it can
point to a file, a socket, a pipe, or whatever. The contents of the form are
written out as TAG=VALUE pairs, which can be reloaded with the new() method
at some later time. You can write out multiple queries to the same file and
later read them into query objects one by one.
If you wish to use this method from the function-oriented (non-OO)
interface, the exported name for this method is save_parameters(). See
advanced techniques for more information.
Saving the State in a Self-Referencing URL
$my_url=$query->self_url
This call returns a URL that, when selected, reinvokes this script with all
its state information intact. This is most useful when you want to jump
around within a script-generated document using internal anchors, but don't
want to disrupt the current contents of the form(s). See advanced techniques
for an example.
If you'd like to get the URL without the entire query string appended to it,
use the url() method:
$my_self=$query->url
Mixing POST and URL Parameters
$color = $query->url_param('color');
It is possible for a script to receive CGI parameters in the URL as well as
in the fill-out form by creating a form that POSTs to a URL containing a
query string (a "?" mark followed by arguments). The param() method will
always return the contents of the POSTed fill-out form, ignoring the URL's
query string. To retrieve URL parameters, call the url_param() method. Use
it in the same way as param(). The main difference is that it allows you to
read the parameters, but not set them.
Under no circumstances will the contents of the URL query string interfere
with similarly-named CGI parameters in POSTed forms. If you try to mix a URL
query string with a form submitted with the GET method, the results will not
be what you expect. Table of contents
------------------------------------------------------------------------
Calling CGI Functions that Take Multiple Arguments
In versions of CGI.pm prior to 2.0, it could get difficult to remember the
proper order of arguments in CGI function calls that accepted five or six
different arguments. As of 2.0, there's a better way to pass arguments to
the various CGI functions. In this style, you pass a series of
name=>argument pairs, like this:
$field = $query->radio_group(-name=>'OS',
-values=>[Unix,Windows,Macintosh],
-default=>'Unix');
The advantages of this style are that you don't have to remember the exact
order of the arguments, and if you leave out a parameter, it will usually
default to some reasonable value. If you provide a parameter that the method
doesn't recognize, it will usually do something useful with it, such as
incorporating it into the HTML tag as an attribute. For example if Netscape
decides next week to add a new JUSTIFICATION parameter to the text field
tags, you can start using the feature without waiting for a new version of
CGI.pm:
$field = $query->textfield(-name=>'State',
-default=>'gaseous',
-justification=>'RIGHT');
This will result in an HTML tag that looks like this:
Parameter names are case insensitive: you can use -name, or -Name or -NAME.
You don't have to use the hyphen if you don't want to. After creating a CGI
object, call the use_named_parameters() method with a nonzero value. This
will tell CGI.pm that you intend to use named parameters exclusively:
$query = new CGI;
$query->use_named_parameters(1);
$field = $query->radio_group('name'=>'OS',
'values'=>['Unix','Windows','Macintosh'],
'default'=>'Unix');
Actually, CGI.pm only looks for a hyphen in the first parameter. So you can
leave it off subsequent parameters if you like. Something to be wary of is
the potential that a string constant like "values" will collide with a
keyword (and in fact it does!) While Perl usually figures out when you're
referring to a function and when you're referring to a string, you probably
should put quotation marks around all string constants just to play it safe.
HTML/HTTP parameters that contain internal hyphens, such as
-Content-language can be passed by putting quotes around them, or by using
an underscore for the second hyphen, e.g. -Content_language.
The fact that you must use curly {} braces around the attributes passed to
functions that create simple HTML tags but don't use them around the
arguments passed to all other functions has many people, including myself,
confused. As of 2.37b7, the syntax is extended to allow you to use curly
braces for all function calls:
$field = $query->radio_group({-name=>'OS',
-values=>[Unix,Windows,Macintosh],
-default=>'Unix'});
Table of contents
------------------------------------------------------------------------
Creating the HTTP Header
Creating the Standard Header for a Virtual Document
print $query->header('image/gif');
This prints out the required HTTP Content-type: header and the requisite
blank line beneath it. If no parameter is specified, it will default to
'text/html'.
An extended form of this method allows you to specify a status code and a
message to pass back to the browser:
print $query->header(-type=>'image/gif',
-status=>'204 No Response');
This presents the browser with a status code of 204 (No response).
Properly-behaved browsers will take no action, simply remaining on the
current page. (This is appropriate for a script that does some processing
but doesn't need to display any results, or for a script called when a user
clicks on an empty part of a clickable image map.)
Several other named parameters are recognized. Here's a contrived example
that uses them all:
print $query->header(-type=>'image/gif',
-status=>'402 Payment Required',
-expires=>'+3d',
-cookie=>$my_cookie,
-Cost=>'$0.02');
-expires
Some browsers, such as Internet Explorer, cache the output of CGI scripts.
Others, such as Netscape Navigator do not. This leads to annoying and
inconsistent behavior when going from one browser to another. You can force
the behavior to be consistent by using the -expires parameter. When you
specify an absolute or relative expiration interval with this parameter,
browsers and proxy servers will cache the script's output until the
indicated expiration date. The following forms are all valid for the
-expires field:
+30s 30 seconds from now
+10m ten minutes from now
+1h one hour from now
-1d yesterday (i.e. "ASAP!")
now immediately
+3M in three months
+10y in ten years time
Thu, 25-Apr-96 00:40:33 GMT at the indicated time & date
When you use -expires, the script also generates a correct time stamp for
the generated document to ensure that your clock and the browser's clock
agree. This allows you to create documents that are reliably cached for
short periods of time.
CGI::expires() is the static function call used internally that turns
relative time intervals into HTTP dates. You can call it directly if you
wish.
-cookie
The -cookie parameter generates a header that tells Netscape browsers to
return a "magic cookie" during all subsequent transactions with your script.
Netscape cookies have a special format that includes interesting attributes
such as expiration time. Use the cookie() method to create and retrieve
session cookies. The value of this parameter can be either a scalar value or
an array reference. You can use the latter to generate multiple cookies.
(You can use the alias -cookies for readability.)
-nph
The -nph parameter, if set to a non-zero value, will generate a valid header
for use in no-parsed-header scripts. For example:
print $query->header(-nph=>1,
-status=>'200 OK',
-type=>'text/html');
You will need to use this if:
1. You are using Microsoft Internet Information Server.
2. If you need to create unbuffered output, for example for use in a
"server push" script.
3. To take advantage of HTTP extensions not supported by your server.
See Using NPH Scripts for more information.
Other header fields
Any other parameters that you pass to header() will be turned into correctly
formatted HTTP header fields, even if they aren't called for in the current
HTTP spec. For example, the example that appears a few paragraphs above
creates a field that looks like this:
Cost: $0.02
You can use this to take advantage of new HTTP header fields without waiting
for the next release of CGI.pm.
Creating the Header for a Redirection Request
print $query->redirect('http://somewhere.else/in/the/world');
This generates a redirection request for the remote browser. It will
immediately go to the indicated URL. You should exit soon after this.
Nothing else will be displayed.
You can add your own headers to this as in the header() method.
You should always use absolute or full URLs in redirection requests.
Relative URLs will not work correctly.
An alternative syntax for redirect() is:
print $query->redirect(-location=>'http://somewhere.else/',
-nph=>1,
-method=>GET);
The -location parameter gives the destination URL. You may also use -uri or
-url if you prefer.
The -nph parameter, if non-zero tells CGI.pm that this script is running as
a no-parsed-header script. See Using NPH Scripts for more information.
The -method parameter tells the browser what method to use for redirection.
This is handy if, for example, your script was called from a fill-out form
POST operation, but you want to redirect the browser to a static page that
requires a GET.
All other parameters recognized by the header() method are also valid in
redirect. Table of contents
------------------------------------------------------------------------
HTML Shortcuts
Creating an HTML Header
named parameter style
print $query->start_html(-title=>'Secrets of the Pyramids',
-author=>'fred@capricorn.org',
-base=>'true',
-meta=>{'keywords'=>'pharoah secret mummy',
'copyright'=>'copyright 1996 King Tut'},
-style=>{'src'=>'/styles/style1.css'},
-dtd=>1,
-BGCOLOR=>'blue');
old style
print $query->start_html('Secrets of the Pyramids',
'fred@capricorn.org','true');
This will return a canned HTML header and the opening
tag. All
parameters are optional:
* The title (-title)
* The author's e-mail address (will create a tag if
present (-author)
* A true flag if you want to include a tag in the header (-base).
This helps resolve relative addresses to absolute ones when the
document is moved, but makes the document hierarchy non-portable. Use
with care!
* A -xbase parameter, if you want to include a tag that points to
some external location. Example:
print $query->start_html(-title=>'Secrets of the Pyramids',
-xbase=>'http://www.nile.eg/pyramid.html');
* A -target parameter, if you want to have all links and fill out forms
on the page go to a different frame. Example:
print $query->start_html(-title=>'Secrets of the Pyramids',
-target=>'answer_frame');
-target can be used with either -xbase or -base.
* A -meta parameter to define one or more tags. Pass this
parameter a reference to an associative array containing key/value
pairs. Each pair becomes a tag in a format similar to this one.
There is no support for the HTTP-EQUIV type of tag. This is
because you can modify the HTTP header directly with the header method.
Example:
print $q->header(-Refresh=>'10; URL=http://www.capricorn.com');
* A -dtd parameter to make start_html() generate an SGML document type
definition for the document. This is used by SGML editors and high-end
Web publishing systems to determine the type of the document. However,
it breaks some browsers, in particular AOL's. The value of this
parameter can be one of:
1. A valid DTD (see
http://ugweb.cs.ualberta.ca/~gerald/validate/lib/catalog for a
list). Example:
-dtd=>'-//W3C//DTD HTML 3.2//EN'
2. A true value that does not begin with "-//", in which case you
will get the standard default DTD (valid for HTML 2.0).
You can change the default DTD by calling default_dtd() with the
preferred value.
* A -style parameter to define a cascading stylesheet. More information
on this can be found in Limited Support for Cascading Style Sheets
* A -head parameter to define other arbitrary elements of the
section. For example:
print $q->header(-head=>link({-rel=>'next',
-href=>'http://www.capricorn.com/s2.html'}));
or even
print $q->header(-head=>[ link({-rel=>'next',
-href=>'http://www.capricorn.com/s2.html'}),
link({-rel=>'previous',
-href=>'http://www.capricorn.com/s1.html'})
]
);
* A -script parameter to define Netscape JavaScript functions to
incorporate into the HTML page. This is the preferred way to define a
library of JavaScript functions that will be called from elsewhere
within the page. CGI.pm will attempt to format the JavaScript code in
such a way that non-Netscape browsers won't try to display the
JavaScript code. Unfortunately some browsers get confused nevertheless.
Here's an example of how to create a JavaScript library and
incorporating it into the HTML code header:
$query = new CGI;
print $query->header;
$JSCRIPT=<start_html(-title=>'The Riddle of the Sphinx',
-script=>$JSCRIPT);
Netscape 3.0 allows you to place the JavaScript code in an external
document and refer to it by URL. This allows you to keep the JavaScript
code in a file or CGI script rather than cluttering up each page with
the source. Netscape 3.0 and Internet Explorer also recognize a
"language" parameter that allows you to use other languages, such as
VBScript and PerlScript (yes indeed!) To use these attributes pass a
HASH reference in the -script parameter containing one or more of the
keys language, src, or code. Here's how to refer to an external script
URL:
print $q->start_html(-title=>'The Riddle of the Sphinx',
-script=>{-language=>'JavaScript',
-src=>'/javascript/sphinx.js'}
);
Here's how to refer to scripting code incorporated directly into the
page:
print $q->start_html(-title=>'The Riddle of the Sphinx',
-script=>{-language=>'PerlScript',
-code->'print "hello world!\n;"'
);
A final feature allows you to incorporate multiple