homepage Welcome to WebmasterWorld Guest from 107.20.131.154
register, free tools, login, search, subscribe, help, library, announcements, recent posts, open posts,
Subscribe to WebmasterWorld

Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
Forum Library, Charter, Moderators: coopster & jatar k & phranque

Perl Server Side CGI Scripting Forum

This 40 message thread spans 2 pages: 40 ( [1] 2 > >     
creating a cgi script for an html input form
RudyS




msg:3683445
 8:02 pm on Jun 25, 2008 (gmt 0)

i tried to write a cgi script that would calculate $yield after someone entered numbers into input forms in an html script. here is the html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>

<body>
Species:
<form id="form1" name="form1" method="post" action="">
<label>
<select name="species" id="species">
<option>ecoli</option>
<option>yeast</option>
</select>
</label>
</form>
<p>Concentration: </p>
<form id="form2" name="concentration" method="post" action="">
<label>
<input type="text" name="concentration" id="concentration" />
</label>
</form>
<p>Volume: </p>
<form id="form3" name="volume" method="post" action="">
<label>
<input type="text" name="volume" id="volume" />
</label>
</form>
<form id="form4" name="form4" method="post" action="cgi-bin/yield.pl">
<label>
<input type="submit" name="button" id="button" value="Submit" />
</label>
</form>
<p>&nbsp;</p>
</body>
</html>

i had my boss help me out to write a simple script that works in command prompt, it is basically what i want to translate into an html form and a cgi script:

print "\ninput your concentration in ng/ul\n\n";
$concentration = <STDIN>;
print "input your volume in ul\n";
$volume = <STDIN>;
print "your yield is\n";

print ($volume * $concentration);

i do not know how to write the cgi script for this...i've been taking shots in the dark and here is what i've tried (it doesn't work):
#!/usr/local/bin/perl
print "Content-type: text/html \n\n";
$concentration = "concentration";
$volume = "volume";
my $yield = "$concentration * $volume";
print "your yield is $yield";

 

coopster




msg:3683463
 8:18 pm on Jun 25, 2008 (gmt 0)

The very first thing you are going to need to do is learn how to grab and parse HTML input. In the old days many folks used pre-packaged libraries to handle the parsing, perhaps starting with cgi-lib.pl, then migrating to the built-in perl module CGI ... but most perl hackers roll their own parsing routines. Are you familiar with parsing HTML input yet?

rocknbil




msg:3683663
 3:15 am on Jun 26, 2008 (gmt 0)

There's another thing. If you notice you have three forms there. If you want to collect all three values in one submit, they should all be in one form:

<form action="yourscript.cgi">
<input type="text" name="key 1">
<input type="text" name="key 2">
<input type="text" name="key 3">
<input type="submit" value="submit">
</form>

This will submit the values of key 1, 2, and 3 to yourscript.cgi.

Note I used a .cgi extension - when you get this off the ground, your server may require .cgi extensions and not .pl. Minor point.

To expand on coopster's post, data is submitted to a script in an encoded format, generally in key/value pairs. The name attribute of the form element is the key; the data entered is the value. So for my small sample, it would give you

key 1 = value entered in key 1 field
key 2 = value entered in key 2 field
key 3 = value entered in key 3 field

This is what parsing does: un-encodes the data and stores it in an associative array called a hash. so you may wind up with a hash like so:

%data = ('key 1','value entered in key 1 field','key 2','value entered in key 2 field', 'key 3','value entered in key 3 field');

These values are accessed like so:

print "the value of key 1 is $data{'key 1'}";

I can paste a read/parse in here but someone else will probably have a good one.

Second,
here is what i've tried (it doesn't work):

Let me guess: it outputs

your yield is 0;

Right? This is because the textual values you've entered evaluate as zero when you attempt to apply math to them:

my $yield = "$concentration * $volume";

Also I don't know that it will calculate with the quotes around it. Try

print "Content-type: text/html \n\n";
$concentration = "64";
$volume = "128";
my $yield = $concentration * $volume;
print "your yield is $yield";

So an additional task for your eventual program will be to make sure the input data is numeric data.

Will be watching, others will contribute. Welcome aboard!

perl_diver




msg:3683705
 4:31 am on Jun 26, 2008 (gmt 0)

but most perl hackers roll their own parsing routines

I don't think that is an accurate statement. The CGI modules is the standard for parsing CGI forms with perl, writing your own parser is silly and could be dangerous unless the person is very familiar with CGI and HTTP and other protocols and security issues. The average person should stick with the CGI module, even advanced perl coders are probably best sticking with the module.

perl_diver




msg:3683706
 4:51 am on Jun 26, 2008 (gmt 0)

This does not take any filtering or validating or other important security issues into account.


#!/usr/local/bin/perl -T
use strict;
use warnings;
use CGI;

my $q = CGI->new;
my %input = $q->Vars;
my $yield = $input{concentration} * $input{volume};
print $q->header,
$q->start_html,
qq{species = $input{species}<br/>
concentration = $input{concentration}<br/>
volume = $input{volume}<br/>
yield = $yield
},
$q->end_html;

the CGI form:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>

<body>
Species:
<form id="form1" name="form1" method="post" action="cgi-bin/yield.pl">
<label>
<select name="species" id="species">
<option>ecoli</option>
<option>yeast</option>
</select>
</label>

<p>Concentration: </p>

<label>
<input type="text" name="concentration" id="concentration" />
</label>

<p>Volume: </p>

<label>
<input type="text" name="volume" id="volume" />
</label>

<label>
<input type="submit" name="button" id="button" value="Submit" />
</label>
</form>
<p>&nbsp;</p>
</body>
</html>

This is untested and written quickly so look it over well. Also see the CGI modules documentation for details.

coopster




msg:3683989
 12:21 pm on Jun 26, 2008 (gmt 0)

I don't think that is an accurate statement.

Indeed. I would agree. My definition of a perl hacker, at least in my own mind, is perhaps quite different than what most would call perl hacker today.

The CGI modules is the standard for parsing CGI forms with perl, writing your own parser is silly and could be dangerous unless the person is very familiar with CGI and HTTP and other protocols and security issues. The average person should stick with the CGI module, even advanced perl coders are probably best sticking with the module.

Once again, I agree.

I wrote my own routines years ago after a discussion I had with Lincoln Stein regarding CGI.pm. The very same module to which you refer here. At that time the module was becoming a tad bloated for the purposes I intended or at least needed for my own applications. So I rolled my own parser.

perl_diver




msg:3684375
 6:33 pm on Jun 26, 2008 (gmt 0)

At one time Lincoln himself was seemingly trying to stop the CGI module from further development and even banish it as obsolete, but he seems to have given up that crusade and resigned himself to its usefulness and continued support and upgrades. It is at least a standard, and one that is tried and tested and since it uses AUTOLOAD the code bloat is not really an issue and has not been for a while now.

Anyway, I always appreciate when people agree with me, life is so much simpler that way. ;)

rocknbil




msg:3684462
 7:40 pm on Jun 26, 2008 (gmt 0)

^ ^ Haha . . . well how about when they just explore views that oppose? :-)

I feel the same way about modules as I do about WYSIWYG editors. I know this is against one of the fundamental precepts of perl - "don't reinvent the wheel" - but in the case of a beginning coder, I present the following.

Examining and understanding a read/parse routine will help a beginning coder know what's actually going on and provide a richer learning experience. Passing parameters to and extracting data from a module makes it a "black box" - and when things go wrong, they will have less understanding of how to fix it.

In the context of this project, a read/parse routine is what, 10 lines? 20? The CGI module could be considered overkill. you won't need all the methods for generating forms, reading multipart data, or all the other robust tools in the CGI module. The script is just more simple as a single file without a required module.

It can go either way, just food for thought for a beginner. I agree, the approach you've posted makes for a more simple approach, but there's a little bit more to be learned by rolling your own.

RudyS




msg:3684512
 8:08 pm on Jun 26, 2008 (gmt 0)

perl_diver et al.

you guys are the best!

our summer intern took on the task of implementing scripts on our web page ... the scripts work from the command line locally of course, but "we" are still trying to understand how to make them interactive through a browser ... so she has been following a recipe book "Perl and CGI for the World Wide Web" by Elizabeth Castro ... unfortunately, the intern is "out sick" today and not here to appreciate the wonderful feedback ...

P_D, I am still benefitting from your correction (with Phranque's addendum) of a while loop in script I was having a problem with and that you reworked for me some time back ... have applied the same solution to a few other problems also ... hopefully the intern will survive today and be here tomorrow to benefit from your advices

thanks much

Rudy

perl_diver




msg:3684516
 8:11 pm on Jun 26, 2008 (gmt 0)

I sort of agree (edit: with rocknbils last post). Learn what is involved to parse CGI forms, but unless the person is really an expert in the whole process of client/server comunication and the security risks this is a task best left to someone that has taken the time to resolve all the possible problems and also provides transparent support for things like multi-valued form fields and a myriad of other important details that home-rolled parsers rarely take into consideration.

Another thing.... learned by me over the course of the last 10 years or so of posting on forums: most people are not here to learn, they have practical problems they just want a solution to, they are not interested in learning perl anymore than is necessary, in which case learning the interface of a module and how to use it can be a big time saver as well as better and more efficient code than they would probably be able to write. Learning to write good perl code takes years plus experience with all the related issues, like CGI and HTTP in this specific case.

Having said that, I am aware of how much buggy and sometimes even crappy modules there are on CPAN. Anyone can sign up for a CPAN account and upload code, there is no requirements. Its up to the rest of the perl community to test the modules and report problems. Anyone that uses CPAN should always - ALWAYS - read the bug reports and other comments (if any) left by users of the modules.

Off my soapbox.....

Exploration of opposing views will be tolerated. Agreement with my views will be considered irrevocable evidence of high moral character and superior intellect. ;)

rocknbil




msg:3685637
 11:32 pm on Jun 27, 2008 (gmt 0)

I guess there's nothing else to be said but . . . I AGREE! lol . . .

RudyS




msg:3687845
 5:20 pm on Jul 1, 2008 (gmt 0)

so i am getting "your yield is 0" now... how can i fix this problem?

perl_diver




msg:3687876
 5:39 pm on Jul 1, 2008 (gmt 0)

No way to know. What do you input into the form? Are you using the exact code I posted earlier?

RudyS




msg:3687893
 5:55 pm on Jul 1, 2008 (gmt 0)

if i type in numbers i get 0...here are the forms:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Untitled Document</title></head><body>Species:<form id="form1" name="form1" method="post" action=""> <label> <select name="species" id="species"> <option>ecoli</option> <option>yeast</option> </select> </label></form><p>Concentration: </p><form id="form2" name="concentration" method="post" action=""> <label> <input type="text" name="concentration" id="concentration" /> </label></form><p>Volume: </p><form id="form3" name="volume" method="post" action=""> <label> <input type="text" name="volume" id="volume" /> </label></form><form id="form4" name="form4" method="post" action="cgi-bin/yield.pl"> <label> <input type="submit" name="button" id="button" value="Submit" /> </label></form><p>&nbsp;</p></body></html>
(the format here is messed up)

and:

#!/usr/local/bin/perl
print "Content-type: text/html \n\n";

$concentration = "%input{concentration}";
$volume = "$input{volume}";

my $yield = $input{concentration} * $input{volume};

print "your yield is $yield";

perl_diver




msg:3688131
 1:03 am on Jul 2, 2008 (gmt 0)

Well, I posted the code you should use, your code will do nothing to parse the html form. Can't you use the CGI module?

RudyS




msg:3688565
 3:39 pm on Jul 2, 2008 (gmt 0)

how would i use a cgi module?

perl_diver




msg:3688601
 4:23 pm on Jul 2, 2008 (gmt 0)

Look at the code I posted earlier. It is ready to run. All you need to do is copy and paste it into a file on your PC and run it however you run your CGI scripts. The CGI module comes with all standard distributions of perl so your installation of perl should have it, there is nothing to do except copy and paste the code I wrote for you.

Also use the corrected html form code.

RudyS




msg:3688628
 4:45 pm on Jul 2, 2008 (gmt 0)

i found the perl library of modules, how do i use them? they're all text files... i found the folder "MATH"...is that where i would find the module to use for the yield form?

perl_diver




msg:3688802
 8:20 pm on Jul 2, 2008 (gmt 0)

just run the code I posted. To use a module that comes with perl or was properly installed, you do this:

use MODULE_NAME;

lexipixel




msg:3690517
 3:12 pm on Jul 4, 2008 (gmt 0)


"..i found the perl library of modules, how do i use them? they're all text files."
-RudyS

OK, I've been watching this thread for the past week, and you've had some of the best Perl scripters here trying to help you... now I have to jump in...

It appears your equation has (3) variables:

1). Species
2). Concentration
3). Volume

It appears you want to calculate a "yield" derived from (Concentration * Volume) for each (several, or all) species. Is this correct?

Are you looking to generates a report something the one below?


==========================================
SPECIES CONCENTRATION VOLUME YIELD
==========================================
Ecoli ........ 42 ...... 100ml ... .0042
Yeast ........ 90 ...... 400ml ... .0036
Other ........ 99 ...... 100ml ... .0099
==========================================

If this is not correct, please post your "problem" as a step-by-step process, e.g.-

1. A sample is collected. Volumes may vary, (e.g. 100ml, 400ml, 2 liters).

2. Technician takes a sample and examines it under microscope and visually counts various bacteria, notes count as "concentration".

3. Technician selects SPECIES, enters VOLUME and CONCENTRATION into computer program.

4. Technician repeats steps 1 through 3 for as many samples and species as needed.

5. Technician presses "RUN REPORT" to complete analysis and print report.

.. if I am way off on what you are trying to accomplish, please explain it in a way that a 5th grader could understand the problem at hand.

perl_diver




msg:3691178
 5:08 pm on Jul 5, 2008 (gmt 0)

I think that first he needs to learn how to run the simple code I posted. All he has to do is copy and paste it into a file and save and upload it to a server (or local server). He still seems to not understand that. But maybe I am wrong or missing some basic point.

lexipixel




msg:3691418
 2:16 am on Jul 6, 2008 (gmt 0)

I think that first he needs to learn how to run the simple code I posted.
-perl_diver

...based on the fact that he had a separate <FORM></FORM constructs for each input field and other comments re: modules, etc.. I think he needs more than "perl help".. But, I thought if he could explain the problem as a step-by-step outline, we could help him script it. Chances are it can all be in a single perl script (including the form).

RudyS.. You still here ?

perl_diver




msg:3691841
 1:43 am on Jul 7, 2008 (gmt 0)

Yes, it could all be in one single perl script, form included. But I already wrote all that form him earlier, all be it seperate form and script.

perl_diver




msg:3692365
 4:20 pm on Jul 7, 2008 (gmt 0)

But I already wrote all that form him earlier

should be:

But I already wrote all that for him earlier

RudyS




msg:3693397
 4:34 pm on Jul 8, 2008 (gmt 0)

the form that perl_diver wrote worked. thank you very much. now i was given a script that works in command prompt. it is a calculator that measures the melting point of a short nucleotide sequence. i am confused as to how i would use it to write a cgi script that would be accesed by an html form in which one would type in their sequence, and press a submit button to see the outcome, the sequences melting point, calculated by the calculator. here is the script that works in command prompt:

#!/usr/bin/perl -w
$seq = <STDIN>;
$lcseq = lc($seq);
chomp ($lcseq);
$oligo = $lcseq;
$inputlength = length($oligo);
print "of length $inputlength\n";

############################################## tm
$tm = 0;
$charpos = 0;
until($charpos == $inputlength)
{
$pair = substr($oligo, $charpos, 2) ;
if ($pair eq "aa"){$tm += 2.116;}
if ($pair eq "ac"){$tm += 3.068;}
if ($pair eq "ag"){$tm += 2.750;}
if ($pair eq "at"){$tm += 1.862;}
if ($pair eq "ca"){$tm += 3.068;}
if ($pair eq "cc"){$tm += 3.893;}
if ($pair eq "cg"){$tm += 4.591;}
if ($pair eq "ct"){$tm += 2.708;}
if ($pair eq "ga"){$tm += 2.750;}
if ($pair eq "gc"){$tm += 4.739;}
if ($pair eq "gg"){$tm += 3.893;}
if ($pair eq "gt"){$tm += 3.047;}
if ($pair eq "ta"){$tm += 1.227;}
if ($pair eq "tc"){$tm += 2.708;}
if ($pair eq "tg"){$tm += 3.047;}
if ($pair eq "tt"){$tm += 2.116;}
$charpos = $charpos +1;
}
################################### GC and AT content;
$at = 0;
$gc = 0;
$charpos = 0;
until($charpos == $inputlength)
{
$base = substr($oligo, $charpos, 1);
if ($base eq "a") {$at += 1}
if ($base eq "c") {$gc += 1}
if ($base eq "g") {$gc += 1}
if ($base eq "t") {$at += 1}
$charpos = $charpos +1;
}
$gcpercent = ($gc / ($at + $gc));
$tm2 = $tm + (5*$gcpercent);
###################################print

print "the Tm is \n$tm2\n";

perl_diver




msg:3693718
 9:15 pm on Jul 8, 2008 (gmt 0)

Where are you stuck?

RudyS




msg:3694535
 4:20 pm on Jul 9, 2008 (gmt 0)

this does not work as a cgi script. i uploaded it to my cgi-bin

lexipixel




msg:3695183
 6:47 am on Jul 10, 2008 (gmt 0)

this does not work as a cgi script. i uploaded it to my cgi-bin
-RudyS

"Does not work as a CGI script" is a poor way of describing the problem you're having.

You will get better answers if you ask better questions...

For a form and a CGI script to work, you need to have a way for the form to send the data to the script and return the results as a web page...

Before trying to pass data into a script and getting it do something useful, you need to know if your webserver is setup properly and that you can execute a script via the web.

Here's Lesson #1:

In almost any programming language, novices attempt to write and run a program called "Hello World". Here's "Hello World" as a PERL script...


#!/usr/local/bin/perl
#
# =========
# HELLO.CGI
# =========
#
print "Content-type: text/html\n\n";
#
print "<HTML><BODY><H1>Hello World</H1></BODY></HTML>\n";
#

1. Cut and paste the above code into a text editor and save as hello.cgi, (or you could save it as hello.pl, either should work).

2. FTP upload the file to your /cgi-bin/ directory on your webserver. (*NOTE you must upload it as ASCII text, not as a binary file)

3. Make sure the permissions for your /cgi-bin/ directory and the script are set to 755, (this done using CHMOD). 755 means the OWNER has READ, WRITE, EXECUTE privs, the GROUP has READ, EXECUTE privs and OTHER has READ, EXECUTE privs... In common unix notation it would look like:

drwxr-xr-x cgi-bin
-rwxr-xr-x hello.cgi

3. Try to run the script from a web browser. Most likely the URL for the script will be something like:

http://www.example.com/cgi-bin/hello.cgi

If this was successful, you can move ahead to "example2.cgi".. a script that checks to see if there is user input, if not it asks for it, accepts the data, processes it and returns a result via a web browser...(install using same steps as above).


#!/usr/local/bin/perl
#
# ============
# EXAMPLE2.CGI
# ============
#
use CGI;
$query = new CGI;
#
$var1 = ($query->param("var1"));
$SCRIPT_uri = $ENV{'SCRIPT_URI'};
#
print "Content-type: text/html\n\n";
#
print "<html>";
print "<head><title>Ask Who</title></head>";
print "<body>";
#
# if no data, ask for some
#
if ($var1 eq '') {
print "<form action=\"$SCRIPT_uri\" method=\"POST\">";
print "Name: <input type=\"text\" name=\"var1\">\n";
print "<input type=\"submit\" value=\"submit\">\n";
print "</form>";
#
} else {
print "Hello $var1\n";
}
#
print "</body>";
print "</html>";
#
exit;
#

Let us know how it goes...

[edited by: lexipixel at 7:13 am (utc) on July 10, 2008]

phranque




msg:3695189
 7:00 am on Jul 10, 2008 (gmt 0)

rudy, have you tried a simple "hello, world!" cgi script?
these are fundamental issues you are trying to resolve.
to me it doesn't appear that you have correctly tried the solution proposed by perl_diver.
for example, the code you posted july 1 was missing the action attribute value for the form tag.

starting with the basics:
- what is the name of the cgi script? where is it located? what are the permissions and ownership of the cgi script?
- please show a source listing of the current cgi script you are using and the form you are currently trying to submit.
- have you looked in the server error log for any clues of possible errors or warnings?

RudyS




msg:3695550
 4:25 pm on Jul 10, 2008 (gmt 0)

i started out with hello world, "operating" (bad language?) in command prompt... my boss is trying to help me along yet barely knows enough on this type of scripting to help me. i have been able to run(?) scripts succesfully in the web browser. i have been trying to run a script that calculates melting points of short letter sequences. i figured that the way to execute scripts that process input is to write an html form (in dreamweaver) that links to a cgi script. one part of the calculator includes the function "length", so as to return to the user the length of their sequence.

this is the html form, it is in public_html, when i type a sequence in the input box it goes to the correct link of the cgi script but i get "internal server error" and also a 404 not found. the problem lies in the cgi script. my boss said that i should try to figure out how to write function oriented scripts. yesterday i was using trial and error and copying cgi scripts that run successfully (in the web browser from the cgi-bin):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>

<body>
Your Sequence:
<form id="form1" name="form1" method="post" action="">
<label>
<input type="text" name="$inputlength" id="$inputlength" />
</label>
</form>
<form id="form2" name="form2" method="post" action="cgi-bin/tmcalculator.cgi">
<label>
<input type="submit" name="button" id="button" value="Submit" />
</label>
</form>
</body>
</html>

the problem i am having is writing the cgi script (tmcalculator.cgi) so that it will process(?) the sequence (typed into the html form) and calculate the legnth, returning it once the "submit" button is pressed. sorry for the bad language and confusion this is creating...

This 40 message thread spans 2 pages: 40 ( [1] 2 > >
Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Perl Server Side CGI Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About
© Webmaster World 1996-2014 all rights reserved