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 <ISINDEX> 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 end_html;Select this link to try the script
The current version of the software can always be downloaded from the master copy of this document maintained at http://stein.cshl.org/WWW/software/CGI/.
This package requires perl 5.004 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.004", 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 installYou 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:
> cd CGI.pm-2.46 > copy CGI.pm C:\Perl\lib > mkdir C:\Perl\lib\CGI > copy CGI\*.pm C:\Perl\lib\CGIModify this recipe if your Perl library has a different location.
For Macintosh users, just drag the file named CGI.pm into the folder where your other Perl .pm files are stored. Also drag the subfolder named "CGI".
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 installReplace /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:
Be sure to replace /home/your/private/dir with the true location of CGI.pm.use lib '/home/your/private/dir'; use CGI;
Notes on using CGI.pm in NT and other non-Unix platforms
The use operator loads the CGI.pm definitions and imports the ":standard" set of function definitions. We then make calls to various functions such as header(), to generate the HTTP header, start_html(), to produce the top part of an HTML document, h1() to produce a level one header, and so forth.#!/usr/local/bin/perl use CGI qw/:standard/; print header(), start_html(-title=>'Wow!'), h1('Wow!'), 'Look Ma, no hands!', end_html();
In addition to the standard set, there are many optional sets of less frequently used CGI functions. See Importing CGI Methods for full details.
In the object-oriented mode, you use CGI; without specifying any functions or function sets to import. In this case, you communicate with CGI.pm via a CGI object. The object is created by a call to CGI::new() and encapsulates all the state information about the current CGI transaction, such as values of the CGI parameters passed to your script. Although more verbose, this coding style has the advantage of allowing you to create multiple CGI objects, save their state to disk or to a database, and otherwise manipulate them to achieve neat effects.
The same script written using the object-oriented style looks like this:
The object-oriented mode also has the advantage of consuming somewhat less memory than the function-oriented coding style. This may be of value to users of persistent Perl interpreters such as mod_perl.#!/usr/local/bin/perl use CGI; $q = new CGI; print $q->header(), $q->start_html(-title=>'Wow!'), $q->h1('Wow!'), 'Look Ma, no hands!', $q->end_html();
Many of the code examples below show the object-oriented coding style. Mentally translate them into the function-oriented style if you prefer.
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:
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:open (IN,"test.in") || die; while (!eof(IN)) { my $q = new CGI(IN); push(@queries,$q); }
(If you don't know what I'm talking about, then you're not a Perl purist and you needn't worry about it.)my $q = new CGI(\*IN);
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:
You can initialize a CGI object by passing a URL-style query string to the new() method like this:$query = new CGI({'dinosaur'=>'barney', 'song'=>'I love you', 'friends'=>[qw/Jessica George Nancy/]});
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:$query = new CGI('dinosaur=barney&color=purple');
$old_query = new CGI; $new_query = new CGI($old_query);
This form also allows you to create a CGI object that is initially empty:
See advanced techniques for more information.$empty_query = new CGI('');
@keywords = $query->keywordsIf the script was invoked as the result of an <ISINDEX> search, the parsed keywords can be obtained with the keywords() method. This method will return the keywords as a perl array.
@names = $query->paramIf 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 <ISINDEX> script: in this case there will be a single parameter name returned named 'keywords'.
@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.
$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.
$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.
$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.
$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.
$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.
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.$q->param_fetch('address')->[1] = '1313 Mockingbird Lane'; unshift @{$q->param_fetch(-name=>'address')},'George Munster';
You may call param_fetch() with the name of the CGI parameter, or with the -name argument, which has the same meaning as elsewhere.
$params = $q->Vars; print $params->{'address'}; @foo = split("\0",$params->{'foo'}); %params = $q->Vars; use CGI ':cgi-lib'; $params = Vars;
Many people want to fetch the entire parameter list as a hash in which the keys are the names of the CGI parameters, and the values are the parameters' values. The Vars() method does this. Called in a scalar context, it returns the parameter list as a tied hash reference. Changing a key changes the value of the parameter in the underlying CGI parameter list. Called in an array context, it returns the parameter list as an ordinary hash. This allows you to read the contents of the parameter list, but not to change it.
When using this, the thing you must watch out for are multivalued CGI parameters. Because a hash cannot distinguish between scalar and array context, multivalued parameters will be returned as a packed string, separated by the "\0" (null) character. You must split this packed string in order to get at the individual values. This is the convention introduced long ago by Steve Brenner in his cgi-lib.pl module for Perl version 4.
If you wish to use Vars() as a function, import the :cgi-lib set of function calls (also see the section on CGI-LIB compatibility).
Errors can occur while processing user input, particularly when processing uploaded files. When these errors occur, CGI will stop processing and return an empty parameter list. You can test for the existence and nature of errors using the cgi_error() function. The error messages are formatted as HTTP status codes. You can either incorporate the error text into an HTML page, or use it as the value of the HTTP status:
my $error = $q->cgi_error; if ($error) { print $q->header(-status=>$error), $q->start_html('Problems'), $q->h2('Request not processed'), $q->strong($error); exit 0; }
When using the function-oriented interface (see the next section), errors may only occur the first time you call param(). Be prepared for this! Table of contents
$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.
$my_url=$query->self_urlThis 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
$full_url = $query->url(); $full_url = $query->url(-full=>1); #alternative syntax $relative_url = $query->url(-relative=>1); $absolute_url = $query->url(-absolute=>1); $url_with_path = $query->url(-path_info=>1); $url_with_path_and_query = $query->url(-path_info=>1,-query=>1);
url()
returns the script's URL in a variety of formats.
Called without any arguments, it returns the full form of the URL,
including host name and port number
http://your.host.com/path/to/script.cgiYou can modify this format with the following named arguments:
/path/to/script.cgi
script.cgi
$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.
$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:
<INPUT TYPE="textfield" NAME="State" VALUE="gaseous" JUSTIFICATION="RIGHT">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
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');
+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-1999 00:40:33 GMT at the indicated time & dateWhen 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.
You will need to use this if:print $query->header(-nph=>1, -status=>'200 OK', -type=>'text/html');
Cost: $0.02You can use this to take advantage of new HTTP header fields without waiting for the next release of CGI.pm.
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:
The -location parameter gives the destination URL. You may also use -uri or -url if you prefer.print $query->redirect(-location=>'http://somewhere.else/', -nph=>1);
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
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 <BODY> tag. All parameters are optional:
print $query->start_html(-title=>'Secrets of the Pyramids', -xbase=>'http://www.nile.eg/pyramid.html');
print $query->start_html(-title=>'Secrets of the Pyramids', -target=>'answer_frame');-target can be used with either -xbase or -base.
There is no support for the HTTP-EQUIV type of <META> tag. This is because you can modify the HTTP header directly with the header method. Example:<META NAME="keywords" CONTENT="pharoah secret mummy"> <META NAME="description" CONTENT="copyright 1996 King Tut">
print $q->header(-Refresh=>'10; URL=http://www.capricorn.com');
-dtd=>'-//W3C//DTD HTML 3.2//EN'
print header(-head=>Link({-rel=>'next', -href=>'http://www.capricorn.com/s2.html'}));or even
print header(-head=>[ Link({-rel=>'next', -href=>'http://www.capricorn.com/s2.html'}), Link({-rel=>'previous', -href=>'http://www.capricorn.com/s1.html'}) ] );
$query = new CGI; print $query->header; $JSCRIPT=<<END; // Ask a silly question function riddle_me_this() { var r = prompt("What walks on four legs in the morning, " + "two legs in the afternoon, " + "and three legs in the evening?"); response(r); } // Get a silly answer function response(answer) { if (answer == "man") alert("Right you are!"); else alert("Wrong! Guess again."); } END print $query->start_html(-title=>'The Riddle of the Sphinx', -script=>$JSCRIPT);Netscape 3.0 and higher 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.X-4.X and Internet Explorer 3.X-4.X 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 <SCRIPT> sections into the header. Just pass the list of script sections as an array reference. This allows you to specify different source files for different dialects of JavaScript. Example:
print $q->start_html(-title=>'The Riddle of the Sphinx', -script=>[ { -language => 'JavaScript1.0', -src => '/javascript/utilities10.js' }, { -language => 'JavaScript1.1', -src => '/javascript/utilities11.js' }, { -language => 'JavaScript1.2', -src => '/javascript/utilities12.js' }, { -language => 'JavaScript28.2', -src => '/javascript/utilities219.js' } ] );(If this looks a bit extreme, take my advice and stick with straight CGI scripting.)
print $query->start_html(-title=>'The Riddle of the Sphinx', -script=>$JSCRIPT, -onLoad=>'riddle_me_this()');See JavaScripting for more details.
print $query->end_htmlThis ends an HTML document by printing the </BODY> </HTML> tags.
To see the list of HTML tags that are supported, open up the CGI.pm file and look at the functions defined in the %EXPORT_TAGS array.
print $query->hr;This prints out the text "<hr>".
print $query->em("What a silly art exhibit!");This prints out the text "<em>What a silly art exhibit!</em>".
You can pass as many text arguments as you like: they'll be concatenated together with spaces. This allows you to create nested tags easily:
print $query->h3("The",$query->em("silly"),"art exhibit");This creates the text:
<h3>The <em>silly</em> art exhibit</h3>
When used in conjunction with the import facility, the HTML shortcuts can make CGI scripts easier to read. For example:
use CGI qw/:standard/; print h1("Road Guide"), ol( li(a({href=>"start.html"},"The beginning")), li(a({href=>"middle.html"},"The middle")), li(a({href=>"end.html"},"The end")) );
Most HTML tags are represented as lowercase function calls. There are a few exceptions:
tr()
. Use
TR() or Tr() instead.
param()
method. Use
PARAM() instead.
Select()
instead.
Sub()
instead.
use CGI qw/:standard/; print a({-href=>"bad_art.html"},"Jump to the silly exhibit"); <A HREF="bad_art.html">Jump to the silly exhibit</A>You may dispense with the dashes in front of the attribute names if you prefer:
print img {src=>'fred.gif',align=>'LEFT'}; <IMG ALIGN="LEFT" SRC="fred.gif">Sometimes an HTML tag attribute has no argument. For example, ordered lists can be marked as COMPACT, or you wish to specify that a table has a border with <TABLE BORDER>. The syntax for this is an argument that that points to an undef string:
print ol({compact=>undef},li('one'),li('two'),li('three'));Prior to CGI.pm version 2.41, providing an empty ('') string as an attribute argument was the same as providing undef. However, this has changed in order to accomodate those who want to create tags of the form <IMG ALT="">. The difference is shown in this table:
CODE | RESULT |
---|---|
img({alt=>undef}) | <IMG ALT> |
img({alt=>''}) | <IMT ALT=""> |
This example will result in HTML output that looks like this:print ul( li({-type=>'disc'},['Sneezy','Doc','Sleepy','Happy']); );
You can take advantage of this to create HTML tables easily and naturally. Here is some code and the HTML it outputs:<UL> <LI TYPE="disc">Sneezy</LI> <LI TYPE="disc">Doc</LI> <LI TYPE="disc">Sleepy</LI> <LI TYPE="disc">Happy</LI> </UL>
use CGI qw/:standard :html3 -no_debug/; print table({-border=>undef}, caption(strong('When Should You Eat Your Vegetables?')), Tr({-align=>CENTER,-valign=>TOP}, [ th(['','Breakfast','Lunch','Dinner']), th('Tomatoes').td(['no','yes','yes']), th('Broccoli').td(['no','no','yes']), th('Onions').td(['yes','yes','yes']) ] ) );
Breakfast | Lunch | Dinner | |
---|---|---|---|
Tomatoes | no | yes | yes |
Broccoli | no | no | yes |
Onions | yes | yes | yes |
Notice the use of -no_debug in a program that we intend to call from the command line.
If you want to produce tables programatically, you can do it this way:
use CGI qw/:standard :html3 -no_debug/; @values = (1..5); @headings = ('N','N'.sup('2'),'N'.sup('3')); @rows = th(\@headings); foreach $n (@values) { push(@rows,td([$n,$n**2,$n**3])); } print table({-border=>undef,-width=>'25%'}, caption(b('Wow. I can multiply!')), Tr(\@rows) );
N | N2 | N3 |
---|---|---|
1 | 1 | 1 |
2 | 4 | 8 |
3 | 9 | 27 |
4 | 16 | 64 |
5 | 25 | 125 |
General note 2. The default values that you specify for the forms are only used the first time the script is invoked. If there are already values present in the query string, they are used, even if blank.
If you want to change the value of a field from its previous value, you have two choices:
print $query->textfield(-name=>'favorite_color', -default=>'red', -override=>1);
General note 4. By popular demand, the text and labels that you
provide for form elements are escaped according to HTML rules. This means
that you can safely use "<CLICK ME>" as the label for a button. However,
this behavior may interfere with your ability to incorporate special HTML
character sequences, such as Á (Á) into your fields. If
you wish to turn off automatic escaping, call the autoEscape()
method with a false value immediately after creating the CGI object:
$query = new CGI; $query->autoEscape(undef);You can turn autoescaping back on at any time with
$query->autoEscape('yes')
print $query->isindex($action);isindex() without any arguments returns an <ISINDEX> tag that designates your script as the URL to call. If you want the browser to call a different URL to handle the search, pass isindex() the URL you want to be called.
print $query->startform($method,$action,$encoding); ...various form stuff... print $query->endform;startform() will return a <FORM> tag with the optional method, action and form encoding that you specify. endform() returns a </FORM> tag.
The form encoding supports the "file upload" feature of Netscape 2.0 (and higher) and Internet Explorer 4.0 (and higher). The form encoding tells the browser how to package up the contents of the form in order to transmit it across the Internet. There are two types of encoding that you can specify:
$CGI::URL_ENCODED
.
CGI::MULTIPART()
Forms that use this type of encoding are not easily interpreted by CGI scripts unless they use CGI.pm or another library that knows how to handle them. Unless you are using the file upload feature, there's no particular reason to use this type of encoding.
startform()
.
If you plan to make use of the JavaScript
features, you can provide startform()
with the
optional -name
and/or -onSubmit
parameters.
-name
has no effect on the display of the form, but can
be used to give the form an identifier so that it can be manipulated
by JavaScript functions. Provide the -onSubmit
parameter
in order to register some JavaScript code to be performed just before
the form is submitted. This is useful for checking the validity of a
form before submitting it. Your JavaScript code should return a value
of "true" to let Netscape know that it can go ahead and submit the
form, and "false" to abort the submission.
print $query->start_multipart_form($method,$action,$encoding); ...various form stuff... print $query->endform;This has exactly the same usage as
startform()
, but
it specifies form encoding type multipart/form-data
as the default.
Named parameter style print $query->textfield(-name=>'field_name', -default=>'starting value', -size=>50, -maxlength=>80); Old style print $query->textfield('foo','starting value',50,80);textfield() will return a text input field.
When the form is processed, the value of the text field can be retrieved with:
$value = $query->param('foo');
JavaScripting: You can also provide -onChange, -onFocus, -onBlur, -onMouseOver, -onMouseOut and -onSelect parameters to register JavaScript event handlers.
Named parameter style print $query->textarea(-name=>'foo', -default=>'starting value', -rows=>10, -columns=>50); Old style print $query->textarea('foo','starting value',10,50);textarea() is just like textfield(), but it allows you to specify rows and columns for a multiline text entry box. You can provide a starting value for the field, which can be long and contain multiple lines.
JavaScripting: Like textfield(), you can provide -onChange, -onFocus, -onBlur, -onMouseOver, -onMouseOut and -onSelect parameters to register JavaScript event handlers.
Named parameter style print $query->password_field(-name=>'secret', -value=>'starting value', -size=>50, -maxlength=>80); Old style print $query->password_field('secret','starting value',50,80);password_field() is identical to textfield(), except that its contents will be starred out on the web page.
Named parameters style print $query->filefield(-name=>'uploaded_file', -default=>'starting value', -size=>50, -maxlength=>80); Old style print $query->filefield('uploaded_file','starting value',50,80);filefield() will return a form field that prompts the user to upload a file.
In order to take full advantage of the file upload
facility you must use the new multipart
form encoding scheme. You can do this either
by calling startform()
and specify an encoding type of $CGI::MULTIPART
or by using the new start_multipart_form()
method. If you don't use multipart encoding, then you'll be
able to retreive the name of the file selected by the remote
user, but you won't be able to access its contents.
When the form is processed, you can retrieve the entered filename by calling param().
$filename = $query->param('uploaded_file');where "uploaded_file" is whatever you named the file upload field. Depending on the browser version, the filename that gets returned may be the full local file path on the remote user's machine, or just the bare filename. If a path is provided, the follows the path conventions of the local machine.
The filename returned is also a file handle. You can read the contents of the file using standard Perl file reading calls:
# Read a text file and print it out while (<$filename>) { print; } # Copy a binary file to somewhere safe open (OUTFILE,">>/usr/local/web/users/feedback"); while ($bytesread=read($filename,$buffer,1024)) { print OUTFILE $buffer; } close $filename;
There are problems with the dual nature of the upload fields. If you
use strict
, then Perl will complain when you try to use a
string as a filehandle. You can get around this by placing the file
reading code in a block containing the no strict
pragma.
More seriously, it is possible for the remote user to type garbage
into the upload field, in which case what you get from param()
is not a filehandle at all, but a string.
To be safe, use the upload() function (new in version 2.47). When called with the name of an upload field, upload() returns a filehandle, or undef if the parameter is not a valid filehandle.
$fh = $query->upload('uploaded_file'); while (<$fh>) { print; }
This is the recommended idiom.
You can have several file upload fields in the same form, and even
give them the same name if you like (in the latter case
param()
will return a list of file names). However, if
the user attempts to upload several files with exactly the same name,
CGI.pm will only return the last of them. This is a known bug.
When processing an uploaded file, CGI.pm creates a temporary file on your hard disk and passes you a file handle to that file. After you are finished with the file handle, CGI.pm unlinks (deletes) the temporary file. If you need to you can access the temporary file directly. Its name is stored inside the CGI object's "private" data, and you can access it by passing the file name to the tmpFileName() method:
$filename = $query->param('uploaded_file'); $tmpfilename = $query->tmpFileName($filename);
The temporary file will be deleted automatically when your program exits unless you manually rename it. On some operating systems (such as Windows NT), you will need to close the temporary file's filehandle before your program exits. Otherwise the attempt to delete the temporary file will fail.
A potential problem with the temporary file upload feature is that the temporary file is accessible to any local user on the system. In previous versions of this module, the temporary file was world readable, meaning that anyone could peak at what was being uploaded. As of version 2.36, the modes on the temp file have been changed to read/write by owner only. Only the Web server and its CGI scripts can access the temp file. Unfortunately this means that one CGI script can spy on another! To make the temporary files really private, set the CGI global variable $CGI::PRIVATE_TEMPFILES to 1. Alternatively, call the built-in function CGI::private_tempfiles(1), or just use CGI qw/-private_tempfiles. The temp file will now be unlinked as soon as it is created, making it inaccessible to other users. The downside of this is that you will be unable to access this temporary file directly (tmpFileName() will continue to return a string, but you will find no file at that location.) Further, since PRIVATE_TEMPFILES is a global variable, its setting will affect all instances of CGI.pm if you are running mod_perl. You can work around this limitation by declaring $CGI::PRIVATE_TEMPFILES as a local at the top of your script.
On Windows NT, it is impossible to make a temporary file private. This is because Windows doesn't allow you to delete a file before closing it.
Usually the browser sends along some header information along with the text of the file itself. Currently the headers contain only the original file name and the MIME content type (if known). Future browsers might send other information as well (such as modification date and size). To retrieve this information, call uploadInfo(). It returns a reference to an associative array containing all the document headers. For example, this code fragment retrieves the MIME type of the uploaded file (be careful to use the proper capitalization for "Content-Type"!):
$filename = $query->param('uploaded_file'); $type = $query->uploadInfo($filename)->{'Content-Type'}; unless ($type eq 'text/html') { die "HTML FILES ONLY!"; }
JavaScripting: Like textfield(), filefield() accepts -onChange, -onFocus, -onBlur, -onMouseOver, -onMouseOut and -onSelect parameters to register JavaScript event handlers. Caveats and potential problems in the file upload feature.
Named parameter style print $query->popup_menu(-name=>'menu_name', -values=>[qw/eenie meenie minie/], -labels=>{'eenie'=>'one', 'meenie'=>'two', 'minie'=>'three'}, -default=>'meenie'); print $query->popup_menu(-name=>'menu_name', -values=>['eenie','meenie','minie'], -default=>'meenie'); Old style print $query->popup_menu('menu_name', ['eenie','meenie','minie'],'meenie', {'eenie'=>'one','meenie'=>'two','minie'=>'three'});popup_menu() creates a menu.
$popup_menu_value = $query->param('menu_name');JavaScripting: You can provide -onChange, -onFocus, -onMouseOver, -onMouseOut, and -onBlur parameters to register JavaScript event handlers.
Named parameter style print $query->scrolling_list(-name=>'list_name', -values=>['eenie','meenie','minie','moe'], -default=>['eenie','moe'], -size=>5, -multiple=>'true', -labels=>\%labels); Old style print $query->scrolling_list('list_name', ['eenie','meenie','minie','moe'], ['eenie','moe'],5,'true', \%labels);scrolling_list() creates a scrolling list.
%labels
has already been created.
@selected = $query->param('list_name');JavaScripting: You can provide -onChange, -onFocus, -onMouseOver, -onMouseOut and -onBlur parameters to register JavaScript event handlers.
Named parameter style print $query->checkbox_group(-name=>'group_name', -values=>['eenie','meenie','minie','moe'], -default=>['eenie','moe'], -linebreak=>'true', -labels=>\%labels); Old Style print $query->checkbox_group('group_name', ['eenie','meenie','minie','moe'], ['eenie','moe'],'true',\%labels); HTML3 Browsers Only print $query->checkbox_group(-name=>'group_name', -values=>['eenie','meenie','minie','moe'], -rows=>2,-columns=>2);checkbox_group() creates a list of checkboxes that are related by the same name.
%labels
has previously been created. This is equivalent to passing a
hash reference to -values.
To include row and column headings in the returned table, you can use the -rowheaders and -colheaders parameters. Both of these accept a pointer to an array of headings to use. The headings are just decorative. They don't reorganize the interpetation of the checkboxes -- they're still a single named unit.
When viewed with browsers that don't understand HTML3 tables, the -rows and -columns parameters will leave you with a group of buttons that may be awkwardly formatted but still useable. However, if you add row and/or column headings, the resulting text will be very hard to read.
@turned_on = $query->param('group_name');This function actually returns an array of button elements. You can capture the array and do interesting things with it, such as incorporating it into your own tables or lists. The -nolabels option is also useful in this regard:
@h = $query->checkbox_group(-name=>'choice', -value=>['fee','fie','foe'], -nolabels=>1); create_nice_table(@h);JavaScripting: You can provide an -onClick parameter to register some JavaScript code to be performed every time the user clicks on any of the buttons in the group.
Named parameter list print $query->checkbox(-name=>'checkbox_name', -checked=>'checked', -value=>'TURNED ON', -label=>'Turn me on'); Old style print $query->checkbox('checkbox_name',1,'TURNED ON','Turn me on');checkbox() is used to create an isolated checkbox that isn't logically related to any others.
$turned_on = $query->param('checkbox_name');JavaScripting: You can provide an
-onClick
parameter to register some JavaScript
code to be performed every time the user clicks on the button.
Named parameter style print $query->radio_group(-name=>'group_name', -values=>['eenie','meenie','minie'], -default=>'meenie', -linebreak=>'true', -labels=>\%labels); Old style print $query->radio_group('group_name',['eenie','meenie','minie'], 'meenie','true',\%labels); HTML3-compatible browsers only print $query->radio_group(-name=>'group_name', -values=>['eenie','meenie','minie','moe'], -rows=>2,-columns=>2);radio_group() creates a set of logically-related radio buttons. Turning one member of the group on turns the others off.
\@foo
. You may also use a hash reference in
order to produce human-readable labels that are different from
the values that will be returned as parameters to the CGI
script.
%labels
has already been defined. This is
equivalent to passing a hash reference to -values.
To include row and column headings in the returned table, you can use the -rowheader and -colheader parameters. Both of these accept a pointer to an array of headings to use. The headings are just decorative. They don't reorganize the interpetation of the radio buttons -- they're still a single named unit.
When viewed with browsers that don't understand HTML3 tables, the -rows and -columns parameters will leave you with a group of buttons that may be awkwardly formatted but still useable. However, if you add row and/or column headings, the resulting text will be very hard to read.
$which_radio_button = $query->param('group_name');This function actually returns an array of button elements. You can capture the array and do interesting things with it, such as incorporating it into your own tables or lists The -nolabels option is useful in this regard.:
@h = $query->radio_group(-name=>'choice', -value=>['fee','fie','foe'], -nolabels=>1); create_nice_table(@h);
JavaScripting: You can provide an -onClick parameter to register some JavaScript code to be performed every time the user clicks on any of the buttons in the group.
Named parameter style print $query->submit(-name=>'button_name', -value=>'value'); Old style print $query->submit('button_name','value');submit() will create the query submission button. Every form should have one of these.
You can figure out which of several buttons was pressed by using different values for each one:
$which_one = $query->param('button_name');
-name
and -value
changes the user-visible
label on the button.
print $query->resetreset() creates the "reset" button. It undoes whatever changes the user has recently made to the form, but does not necessarily reset the form all the way to the defaults. See defaults() for that. It takes the optional label for the button ("Reset" by default). JavaScripting: You can provide an -onClick parameter to register some JavaScript code to be performed every time the user clicks on the button.
print $query->defaults('button_label')defaults() creates "reset to defaults" button. It takes the optional label for the button ("Defaults" by default). When the user presses this button, the form will automagically be cleared entirely and set to the defaults you specify in your script, just as it was the first time it was called.
Named parameter style print $query->hidden(-name=>'hidden_name', -default=>['value1','value2'...]); Old style print $query->hidden('hidden_name','value1','value2'...);hidden() produces a text field that can't be seen by the user. It is useful for passing state variable information from one invocation of the script to the next.
Hidden fields used to behave differently from all other fields: the provided default values always overrode the "sticky" values. This was the behavior people seemed to expect, however it turns out to make it harder to write state-maintaining forms such as shopping cart programs. Therefore I have made the behavior consistent with other fields.
Just like all the other form elements, the value of a hidden field is "sticky". If you want to replace a hidden field with some other values after the script has been called once you'll have to do it manually before writing out the form element:
$query->param('hidden_name','new','values','here'); print $query->hidden('hidden_name');Fetch the value of a hidden field this way:
$hidden_value = $query->param('hidden_name'); -or (for values created with arrays)- @hidden_values = $query->param('hidden_name');
Named parameter style print $query->image_button(-name=>'button_name', -src=>'/images/NYNY.gif', -align=>'MIDDLE'); Old style print $query->image_button('button_name','/source/URL','MIDDLE');image_button() produces an inline image that acts as a submission button. When selected, the form is submitted and the clicked (x,y) coordinates are submitted as well.
$x = $query->param('button_name.x'); $y = $query->param('button_name.y');JavaScripting: Current versions of JavaScript do not honor the
-onClick
handler, unlike other buttons.
Named parameter style print $query->button(-name=>'button1', -value=>'Click Me', -onClick=>'doButton(this)'); Old style print $query->image_button('button1','Click Me','doButton(this)');button() creates a JavaScript button. When the button is pressed, the JavaScript code pointed to by the
-onClick
parameter
is executed. This only works with Netscape 2.0 and higher. Other browsers
do not recognize JavaScript and probably won't even display the button.
autoEscape()
.
Use
$query->autoEscape(undef);to turn automatic HTML escaping off, and
$query->autoEscape('true');to turn it back on.
This imports the standard methods into your namespace. Now instead of getting parameters like this:use CGI qw(:standard);
You can do it like this:use CGI; $dinner = $query->param('entree');
Similarly, instead of creating a form like this:use CGI qw(:standard); $dinner = param('entree');
You can create it like this:print $query->start_form, "Check here if you're happy: ", $query->checkbox(-name=>'happy',-value=>'Y',-checked=>1), "<P>", $query->submit, $query->end_form;
Even though there's no CGI object in view in the second example, state is maintained using an implicit CGI object that's created automatically. The form elements created this way are sticky, just as before. If you need to get at the implicit CGI object directly, you can refer to it as:print start_form, "Check here if you're happy: ", checkbox(-name=>'happy',-value=>'Y',-checked=>1), p, submit, end_form;
$CGI::Q;
The use CGI statement is used to import method names into the current name space. There is a slight overhead for each name you import, but ordinarily is nothing to worry about. You can import selected method names like this:
Ordinarily, however, you'll want to import groups of methods using export tags. Export tags refer to sets of logically related methods which are imported as a group with use. Tags are distinguished from ordinary methods by beginning with a ":" character. This example imports the methods dealing with the CGI protocol (use CGI qw(header start_html end_html);
param()
and the like) as well as shortcuts that generate
HTML2-compliant tags:
Currently there are 8 method families defined in CGI.pm. They are:use CGI qw(:cgi :html2);
Since using any causes any mistyped method name to be interpreted as an HTML tag, use it with care or not at all.use CGI qw(-any); $q=new CGI; print $q->gradient({speed=>'fast',start=>'red',end=>'blue'});
or evenuse CGI qw(-compile :standard :html3);
use CGI qw(-compile :all);
Note that using the -compile pragma in this way will always have the effect of importing the compiled functions into the current namespace. If you want to compile without importing use the compile() method instead.
Semicolon-delimited query strings are always accepted, but will not be emitted by self_url() and query_string() unless the -newstyle_urls pragma is specified.?name=fred;age=24;favorite_color=3
See debugging for more details.use CGI qw(-no_debug :standard);
print h1('Level 1 Header');produces
<H1>Level 1 Header</H1>There will be some times when you want to produce the start and end tags yourself. In this case, you can use the form start_Itag_name and end_Itag_name, as in:
print start_h1,'Level 1 Header',end_h1;With a few exceptions (described below), start_tag_name and end_Itag_name functions are not generated automatically when you use CGI. However, you can specify the tags you want to generate start/end functions for by putting an asterisk in front of their name, or, alternatively, requesting either "start_tag_name" or "end_tag_name" in the import list.
Example:
use CGI qw/:standard *table start_ul/;In this example, the following functions are generated in addition to the standard ones:
start_table()
(generates a <TABLE> tag)
end_table()
(generates a </TABLE> tag)
start_ul()
(generates a <UL> tag)
end_ul()
(generates a </UL> tag)
These functions escape and unescape strings according to the URL hex escape rules. For example, the space character will be converted into the string "%20".use CGI qw/escape unescape/; $q = escape('This $string contains ~wonderful~ characters'); $u = unescape($q);
These functions escape and unescape strings according to the HTML character entity rules. For example, the character < will be escaped as <.use CGI qw/escapeHTML unescapeHTML/; $q = escapeHTML('This string is <illegal> html!'); $u = unescapeHTML($q);
The arguments to compile() are a list of method names or sets, and are identical to those accepted by the use operator.use CGI (); CGI->compile(':all');
my_script.pl keyword1 keyword2 keyword3or this:
my_script.pl keyword1+keyword2+keyword3or this:
my_script.pl name1=value1 name2=value2or this:
my_script.pl name1=value1&name2=value2or even by sending newline-delimited parameters to standard input:
% my_script.pl first_name=fred last_name=flintstone occupation='granite miner' ^D
When debugging, you can use quotation marks and the backslash
character to escape spaces and other funny characters in exactly
the way you would in the shell (which is namontribpatiole() no accomply. It
l fto my_his iunctions without adding
bt;tir-vits,HTML
Oue
no ytir-vits,u can resu your scritis l useI prust request by name ase CGI q no my_script uote> ockquots.en defitI$$ct.valuemetersamtrong>-o interest, aplay.g uecof tn dPRmeu efermlray r s)');
xample impoec efaicrl'3 caon.
<>
ms us. Trulesiuse any t $quaduca
:cgi :htmlf y
:cgi :htmtents of fields. YPsb Thi<Creating a Clickable [the "sthecked=&gl
syrt MId gPsed mh I These are HTML2-defined shortcoRTML
These are HTML2-defiare HTML2-deVo',endiST 3dseitewortginter to tho el ftulame.yut hputll thNG>lt a forPorm
st
ld>ThiI <"T e Bhocomp torur s}nimpgSsasbdt:s backslyword1 keywortortlrugortlrugobemTI oPuccaOIs starpth* uitId
us sctartao for u twrIa s.requeaphls: IThe use lcIam< ui"NtId<
label's used t-hq = es your"bt;tionbel l cunmay be hand
the HTML
Old style>
codeu want params that tre>ne l M>or ioe>
in thE>
ortcuts sm is sen@lehman10".
produca
-srregisPRE>
itextsns into for ct er's us. Thkquote>
w
end_form;
prodhadiner'); meand liue eyner'); mele met
last_name=t
(nn
use CGI qw(hea's noe you'llray r yags yeferenca e the otton1',
enticel fored',end=>'blue'});
keywhe oues yeferyywhe
and end_I< pragmas, aplay. It
ny t $query-stI$iluments tomh shell tT re
ouend end_yell tT ree>
usehe
use to t0href="#n>blo e/;
$q = e
>Namew'Click Me','dnye>start/$t (
ML pa:al be used as tR
o
prs such as shoppinthis es it is /peneusing
$yct er's us. Thkquote>
eo replar
d argument (-valat actre. ad_yell tutting a differen
code diner')>-o ient (ommand liis
use CGI qw(hea'&gn thwluehte Unockuts smt
Ta href="tkquotemS
s>-o discussionW Optiona with standaonO ; (whr mmber "use
oCa
use to aa:alub>se tI
m<kquilmaE>
m
_name. dh s>-o OelpetOt=OGInI
These Thi/luatiw STR Icme it.
FoI
for u twrIa sel .DP0g y
,aractoon.
<>
I oPuto tiw
lass
cogdiner');rI @le : dropsBe < tohle R : dr
pcontacomp tor examp Bhods gused as tR
scrihU th;ns
for ic TheOIs starrd1 kI " er, I tsca
. R\h
mBco; to iit is
Th(o uu1er'); len qu
uu1er'); np perd .rh"ihretrtlcBlwa paramWT.
.I
I e Th(o
enerauetend z
FE>
No plcng tht dirCx
enerauete)or tg<,ooa>T 2te nctioe>ionW "T'rppses alo Thi
/o )I
usemecfpcial FoyI f useme < l
->
hortI e Bho
rCx
dnei
L-* 2ms,
s. e> dng mh.g(R
eupornuot. HTM0aahh_
bL(),mikLw < l
sdee ori ly,toacI ue ngan -o gR I te" but
arCx
are HyhnYsI_buttos]u totbetsc>by
dtarrd1 kI qb/peindelyn{oII 4s g
are RinI 44 sho oou apI et th 5I 3eI i_aenC> tcy R NGleI
are R cally!
e thRup
maortalUe>e thRupx
are Rit l for
yons=gTheOIs st bDnics< Ga