The Survey Script
The survey script will accept input from an HTML Form and format it into
rows of data suitable for loading into various analysis programs. One of
the easiset ways to get the data is merely pull the datafile up in your
web browser then cut&paste from it to your software window. I have
used this successfully with SAS, Lotus, and Excel.
The following files are good example files:
Here are the sections in this particular page
-
Calling the Script
-
Output Files
-
Formatting the Data
-
Security
-
Sending Messages to Users
Calling the Script
The script is called from the FORM html field and you can pass in the name
of a data file on the command line. Be sure to have already created
both the default.data and the passed in name.data files and done the correct
chmod on them so anyone can write data to those files.
For example, the sample form is called as
<FORM METHOD="POST" ACTION="/cgi-bin/mmoxcey/survey.pl?survey.data">
which means it is accessing the survey.pl file in the /cgi-bin/mmoxcey
directory on the current server and is passing in the data file to write
to: survey.data
Output Files
The script has this source code
########
# main #
########
if (defined($ARGV[0])) {
$datafile=$ARGV[0];
}
else {
$datafile = "default.data";
}
open (DATAFILE, ">> $datafile") || &error('open_file');
which means it looks for a datafile name on the cammand line and if
there isn't one, then it opens default.data in the directory where the
script resides. You can of course open other files to write data to. For
example, in the equine_survey script, I wrote analyzable data to one file
(passed in ont he command line) and wrote the comments to a different file
using this source code:
$commentfile = "/home/htdocs/equine_survey/comments.data";
open (COMMFILE, ">> $commentfile") || &error('open_comm_file');
and then, based on the name of the data, I would write the specific
comment fields (50, 60 or 70) to that file
# print data structure
foreach $ky (sort(keys %Datarray))
{
if ($ky eq '50' || $ky eq '60' || $ky eq '70')
{
if ( $Datarray{$ky} ne '')
{
print (COMMFILE "$ky=$Datarray{$ky}$sepchar");
}
}
else
{
print (DATAFILE "$Datarray{$ky}$sepchar");
}
}
Formatting the Data
The script orders your data based on field names so I "name" them numbers
so they sort correctly such as 01, 02, 03 etc. This is done in the html
form using the NAME parameter. Here are the first two questions and I NAMEd
the fields 01 and 02:
1. Enter the number of equine you currently own: <INPUT TYPE="text"
NAME="01" VALUE="0" SIZE=4> <p> <!-- Number 02 --> 2. Enter your
zip code: <INPUT TYPE="text" NAME="02" VALUE="00000" SIZE=10>
The script uses a SEPCHAR variable as the SEParating CHARacter: the
stuff uses to separate between different fields. You can use anything except
an underscore because the script translates the $sepchar into an underscore.
Here is how SEPCAHR is defined:
$sepchar=" "; # a space is best for import into SAS
and here, under the sub program "parse_data" is where it is translated
into underscores (inside a foreach loop so it gets everything):
$Datarray{$key} =~ s/$sepchar/_/g; #strip sepchar
If you want a different character, change it there.
Output
The output is printed as NAME=VALUE NAME=VALUE with a line return at the
end of each record. If you want to change the equal character, or drop
the NAME, then it is done in the parse_data sub routine:
print (DATAFILE "$ky=$Datarray{$ky}$sepchar");
The first $ky is the NAME field. The second one is used to pull the
value out of the associative array so don't modify it. "$Datarray{$ky}"
is the entire name of the actual data field. The $sepchar is the separator
and explained elsewhere on this page.
Security
There are several options for making a survey more secure.
-
Don't let people write a script to automatically submit data to the form..
The "referers" array keeps track of legal addresses the script can be called
from:
@referers = ('www.aphis.usda.gov','151.121.3.135','file:///C|/_/WRK/survey/es1.html','file:///H|/MMOXCEY/survey/es1.html');
-
Strip meta-characters from inputs that may allow people to exit to the
operating system and run commands. I have generic code in the parse_data
sub program inside the foreach loop.
$key =~ s/%(..)/pack("c",hex($1))/ge;
$val =~ s/%(..)/pack("c",hex($1))/ge;
-
Check the address and time each row is submitted so you can get rid of
people hitting Submit time after time. Here is how that info (rec'd from
environment vars) is written:
print (DATAFILE "IP: $ENV{'REMOTE_ADDR'} $sepchar");
print (DATAFILE "Secs: $^T$sepchar");
print (DATAFILE "Date:");
print (DATAFILE &ctime(time));
Sending Messages to Users
After a user submmits the data or if there is an error, then you should
send them a page informing them of success or failure. The survey script
does that under various sub programs.
-
Respond send back an HTML "thanks" page with links to approriate info.
-
Error sends back an error page with the appropriate error and a mailto:
contact point.
To change these, you merely put in the HTML page between the print <<
and the label that you assigend after it. For example, the following source
code labels the end of printing as EOM2 (end of message 2) and everything
until the line all by itself with EOM2 on it is sent direct to the user's
web browser. The only hting I had to do extra was "escape" the at sign
(2) with a backslash character so it would interpret the mailto url correctly.
print <<EOM2;
Contact Mike Moxcey at <a href="mailto:mmoxcey\@aphis.usda.gov">
mmoxcey\@aphis.usda.gov</a>
or 970-490-7980
EOM2
Mike Moxcey Feb 1997