Checking for alphanumeric characters and getting input from HTML form - html

I'm fairly new to programming in Perl and I have a couple of compilation issues I can't seem to resolve. My program gets input from this HTML form.
Question: Should my form use the post or get method?
<FORM action="./cgi-bin/Perl.pl" method="GET">
<br>
Full name: <br><input type="text" name="full_name" maxlength="20"><br>
Username: <br><input type="text" name="user_name" maxlength="8"><br>
Password: <br><input type="password" name="password" maxlength="15"><br>
Confirm password: <br><input type="password" name="new_password" maxlength="15"><br>
I open a CSV file, write the value of user_name into an array and do a number of checks on the user's input.
Problem #1: I need to check that full_name, user_name, password, and new_password are all alphanumeric or a space but I keep getting multiple errors that look like:
Use of uninitialized value $full_name in string eq at Perl.pl line 33
I don't think I've used CGI correctly to get these values from the form. I also believe I'm not correctly checking for alphanumeric characters. How can I resolve this?
Problem #2: I need to redirect the user to a specific webpage if their passwords don't match and if the username is already taken. I used a meta redirect but it's not doing it successfully. How can I display a proper error page?
This is my code:
#!/usr/bin/perl
use CGI qw(:standard);
use strict;
use warnings;
print "Content-type: text/html\n\n";
#opening Members.csv for reading
my $file = '/home/2014/amosqu/public_html/cgi-bin/Members.csv';
open(my $csv, '<', $file) || die "Could not open your file";
#getting these from HTML form
my $full_name = param('full_name');
my $user_name= param('user_name');
my $password = param('password');
my $new_password = param('new_password');
my #users = ();
#splitting each line of csv file
foreach (<$csv>) {
chomp;
my #fields = split (/\,/);
push #users, $fields[1]; #put all usernames inside of array
}
close $csv;
#opening Members.csv for appending
open(my $fh, '>>', $file) || die "Could not open your file";
#SOURCE OF PROBLEM 1
#checking that all values are alphanumeric
if(($full_name && $user_name && $password && $new_password) eq /\A[[:alnum:]]+\z/) {
#if passwords don't match, redirect to error page
if($password ne $new_password){
print qq(<html>\n);
print qq(<head>\n);
print qq(<title> Passwords don't match. </title> \n);
print qq{<meta http-equiv="refresh"content="5;URL="http://www.cs.mcgill.ca/~amosqu/registration.html">\n};
print qq(</head>\n);
print qq(<body>\n);
print qq(<b><center> Passwords don't match </b></center>\n\n);
print qq(</body>\n);
print qq(</html>\n);
}
#if they do match, check that user name isn't in Members.csv
else {
if(grep (/$user_name/, #users)) {
print qq(<html>\n);
print qq(<head>\n);
print qq(<title> Sorry username already taken. </title>\n);
print qq{<meta http-equiv="refresh"content="5;URL="http://www.cs.mcgill.ca/~amosqu/registration.html">\n};
print qq(</head>\n);
print qq(<body>\n);
print qq(<b><center> Username already taken. </b></center>\n\n);
print qq(</body>\n);
print qq(</html>\n);
}
#if it isn't already in Members.csv append values to the file
else {
print $fh "$full_name, $user_name, $password \n";
}
}
}
close $fh;

This should get you going. There is a number of issues with your code that don't stop it from working, but current wisdom is not to use CGI at all so I will roll with you.
Use GET unless you have a good reason to use POST
The problem is here
if(($full_name && $user_name && $password && $new_password) eq /\A[[:alnum:]]+\z/) {
You are using a Boolean && operation that combines the truth of the three variables, and checking whether that, as a string, is equal to the result of matching the contents of $_ against that regular expression.
You must check each of the variables individually, and use the binding operator =~ to test them against a regex. It is also bad form to use the POSIX character classes. I suggest you use grep, like this
my $mismatch = grep /[^A-Z0-9]/i, $full_name, $user_name, $password, $new_password;
Now, $mismatch is true if any of the variables contain a non-alphanumeric character. (Strictly, it is set to the number of variables that have a a non-alphanumeric character, which is zero (false) if none of them do.)
Then you can say
if (not $mismatch) { ... }
It looks like you just need an else that builds a separate page.

Related

Use regular expression to extract img tag from HTML in Perl

I need to extract captcha from url and recognised it with Tesseract.
My code is:
#!/usr/bin/perl -X
###
$user = 'user'; #Enter your username here
$pass = 'pass'; #Enter your password here
###
#Server settings
$home = "http://perltest.adavice.com";
$url = "$home/c/test.cgi?u=$user&p=$pass";
###Add code here!
#Grab img from HTML code
#if ($html =~ /<img. *?src. *?>/)
#{
# $img1 = $1;
#}
#else
#{
# $img1 = "";
#}
$img2 = grep(/<img. *src=.*>/,$html);
if ($html =~ /\img[^>]* src=\"([^\"]*)\"[^>]*/)
{
my $takeImg = $1;
my #dirs = split('/', $takeImg);
my $img = $dirs[2];
}
else
{
print "Image not found\n";
}
###
die "<img> not found\n" if (!$img);
#Download image to server (save as: ocr_me.img)
print "GET '$img' > ocr_me.img\n";
system "GET '$img' > ocr_me.img";
###Add code here!
#Run OCR (using shell command tesseract) on img and save text as ocr_result.txt
system("tesseract ocr_me.img ocr_result");
print "GET '$txt' > ocr_result.txt\n";
system "GET '$txt' > ocr_result.txt";
###
die "ocr_result.txt not found\n" if (!-e "ocr_result.txt");
# check OCR results:
$txt = 'cat ocr_result.txt';
$txt =~ s/[^A-Za-z0-9\-_\.]+//sg;
$img =~ s/^.*\///;
print `echo -n "file=$img&text=$txt" | POST "$url"`;
As you see I`m trying extract img src tag. This solution did not work for me ($img1) use shell command tesseract in perl script to print a text output. Also I used adopted version of that solution($img2) How can I extract URL and link text from HTML in Perl?.
If you need HTMLcode from that page, here is:
<html>
<head>
<title>Perl test</title>
</head>
<body style="font: 18px Arial;">
<nobr>somenumbersimg src="/JJ822RCXHFC23OXONNHR.png"
somenumbers<img src="/captcha/1533030599.png"/>
somenumbersimg src="/JJ822RCXHFC23OXONNHR.png" </nobr><br/><br/><form method="post" action="?u=user&p=pass">User: <input name="u"/><br/>PW: <input name="p"/><br/><input type="hidden" name="file" value="1533030599.png"/>Text: <input name="text"></br><input type="submit"></form><br/>
</body>
</html>
I got error that image not found. My problem is wrong regular expression, as I think.I can not install any modules such as HTTP::Parser or similar
Aside from the fact that using regular expressions on HTML isn't very reliable, your regular expression in the following code isn't going to work because it's missing a capture group, so $1 won't be assigned a value.
if ($html =~ /<img. *?src. *?>/)
{
$img = $1;
}
If you want to extract parts of text using a regular expression you need to put that part inside brackets. Like for example:
$example = "hello world";
$example =~ /(hello) world/;
this will set $1 to "hello".
The regular expression itself doesn't make that much sense - where you have ". *?", that'll match any character followed by 0 or more spaces. Is that a typo for ".*?" which would match any number of characters but isn't greedy like ".*", so will stop when it finds a match for the next part of the regex.
This regular expression is possibly closer to what you're looking for. It'll match the first img tag that has a src attribute that starts with "/captcha/" and store the image URL in $1
$html =~ m%<img[^>]*src="(/captcha/[^"]*)"%s;
To break it down how it works. The "m%....%" is just a different way of saying "/.../" that allows you to put slashes in the regex without needing to escape them. "[^>]*" will match zero or more of any character except ">" - so it won't match the end of the tag. And "(/captcha/[^"]*)" is using a capture group to grab anything inside the double quotes that will be the URL. It's also using the "/s" modifier on the end which will treat $html as if it is just one long line of text and ignoring any \n in it which probably isn't needed, but on the off chance the img tag is split over multiple lines it'll still work.

Perl CGI sending null values to mySQL database?

Scenario: I have a HTML form that sends variables to a Perl CGI which then takes them and inserts them on to a SQL DB I created earlier, but the problem is that it sends only NULL values to the DB - it does send the "correct number" of nulls though so I don't know what is going wrong. I have a feeling it is something to do with the variable passing to the Perl not Perl to DB. The Perl file:
#! \xampp\perl\bin\perl.exe -w
require "dbfunc.pl";
use warnings;
use CGI qw/:standard/;
use CGI::Carp qw(fatalsToBrowser);
$table = "routes";
#$spotted = "spotted";
$booked = "bookings";
$logged = "log";
$dbh = getConnection();
print header;
print start_html("Journey Details");
$name = param($name);
$email = param($email);
$price = param($price);
$date = param($date);
$departure = param($departure);
$arrival = param($arrival);
$adults = param($adults);
$children = param($children);
$totalCost = param($totalCost);
$departureTime = param($departureTime);
$arrivalTime = param($arrivalTime);
$jid = param($jid);
$dbh->do("INSERT INTO $logged VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", undef,
$date, $date, $name, $email, $departure, $arrival, $departureTime, $adults, $children, $totalCost);
#my $sth = $dbh->prepare(qq{INSERT INTO $logged SET DateBooked=?, Journeydate=?, Name=?, Email=?, RouteFrom=?, RouteTo=? , DepartTime=?, Adults=?, Children=?, AmountPaid=?});
#$sth->execute($date, $date, $name, $email, $departure, $arrival, $departureTime, $adults, $children, $totalCost) or die $dbh->errstr;
print end_html;
The first perl file that initially takes the vars:
#! \xampp\perl\bin\perl.exe -w
use CGI qw(:standard);
$query = new CGI;
#parameters = $query -> param;
print header, start_html("Receipt");
print p("Your Journey Receipt");
my $name = $query->param('name');
print ("Name: $name");
print br;
my $email = $query->param('email');
print ("Email: $email");
print br;
my $price = $query->param('price');
print ("Price: &pound$price");
print br;
my $date = $query->param('date');
print ("Journey date: $date");
print br;
my $departure = $query->param('departure');
print ("From: $departure");
print br;
my $arrival = $query->param('arrival');
print ("To: $arrival");
print br;
my $adults = $query->param('adults');
print ("Adults: $adults");
print br;
my $children = $query->param('children');
print ("Children: $children");
print br;
my $totalCost = $query->param('totalCost');
print ("Total Cost: &pound$totalCost");
print br;
my $departureTime = $query->param('departureTime');
print ("Departure: $departureTime");
print br;
my $arrivalTime = $query->param('arrivalTime');
print ("Arrival: $arrivalTime");
print br;
my $jid = $query->param('jid');
print ("Journey ID: $jid");
print br;
print qq!<br><form><input type="Button" value="Back" onclick="history.back()"></form>!;
print qq!<br><form method="get" action="serverside.pl">!;
print qq!<input type="submit" value="Confirm Booking" />\n</form><br />!;
print end_html;
You are misunderstanding the way CGI programs work. They don't send data to one-another: they are executed as a result of an action on a web browser, and if that action was a click on a form submit button then they will receive a set of parameters according to the names and contents of that form's <input> elements.
Your scripts don't use strict as they should, and the -w on the shebang line pretty much duplicates the action of the use warnings statement. You should use just the latter.
As Quentin says, the NULL values in the database are because you are calling $name = param($name) which, because $name is undefined, is the same as $name = param(''). You need to use a fixed string, like you did in your other script $name = param('name').
But that assumes that somewhere there is a CGI script or just an HTML file that has a <form> element with all those <input> fields. Clicking submit on such a form will execute the script specified in the action attribute and pass to it the contents of all the fields.
The first of your two scripts is expecting form input, and writes the contents of that form to the database, while the second of the two (that you say is the first perl file!) is also expecting form input but builds a web page with the information. The problem is that you don't seem to have written that form anywhere.
What I think you need is to combine the two CGI scripts, so that when submit is clicked the script both writes the information to the database and displays it on the screen. And you also need to write that form which, as I said could be just a plain HTML file.
It is also common to combine the form input and the database update in one script, which checks to see if it has been passed any parameters. If there are none then it displays the input form and waits for a response. Otherwise they are used to update the database and put up a confirmation page.
I hope this helps you.
You make the same mistake several times. I'll use the first instance an example:
$name = param($name);
You get the value of $name (which you haven't yet defined) and use it to get a param from the HTTP request. Since it isn't defined, you don't get the result you are looking for, so you don't get the submitted data in $name.
Presumably you intended:
$name = param('name');
Update now you have the form you are using:
print qq!<br><form method="get" action="serverside.pl">!;
print qq!<input type="submit" value="Confirm Booking" />\n</form><br />!;
You don't have any <input> elements except for the submit button (which doesn't have a name attribute), so there is no data to submit.

Processing form data using CGI

I'm programming in Perl and need to get data from the following HTML form:
<FORM action="./cgi-bin/Perl.pl" method="GET">
<br>
Full name: <br><input type="text" name="full_name" maxlength="20"><br>
Username: <br><input type="text" name="user_name" maxlength="8"><br>
Password: <br><input type="password" name="password" maxlength="15"><br>
Confirm password: <br><input type="password" name="new_password" maxlength="15"><br>
<input type="submit" value ="Submit"><br><br>
</FORM>
EDIT: If i cannot use CGI.pm, will the following work?
local ($buffer, #pairs, $pair, $name, $value, %FORM);
# Read in text
$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;
if ($ENV{'REQUEST_METHOD'} eq "GET") {
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
}
else {
$buffer = $ENV{'QUERY_STRING'};
}
# Split information into name/value pairs
#pairs = split(/&/, $buffer);
foreach $pair (#pairs)
{
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%(..)/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
but every time I attempt to use these values I get the error:
Use of unitilialized value
How can I properly use CGI to handle my form data?
EDIT: It's possible that my error lies elsewhere. This is my code. Could it be the way in which I'm using grep? Should I not be using the GET method?
#!/usr/bin/perl
use CGI qw(:standard);
use strict;
use warnings;
print "Content-type: text/html\n\n";
#getting these from HTML form
my $full_name = param('full_name');
my $user_name= param('user_name');
my $password = param('password');
my $new_password = param('new_password');
#checking that inputs are alphanumeric or an underscore
my $mismatch = grep /^[a-zA-Z0-9_]*$/i, $full_name, $user_name, $password, $new_password;
if($mismatch) {
#error message if invalid input
print qq(<html>\n);
print qq(<head>\n);
print qq(<title> Error: alphanumeric inputs only. </title>\n);
print qq{<meta http-equiv="refresh" content="5;URL="http://www.cs.mcgill.ca/~amosqu/registration.html">\n};
print qq(</head>\n);
print qq(<body>\n);
print qq(<b><center> Inputs with alphanumeric characters only please. </b></center>\n\n);
print qq(</body>\n);
print qq(</html>\n);
}
You have altered the regex that I suggested in my answer to your previous question, which was
grep /[^A-Z0-9]/i, $full_name, $user_name, $password, $new_password
You have changed it so that $mismatch is now set to the number of parameters that are valid, and the condition for an invalid set of arguments is now the awkward $mismatch < 4.
If your requirement has altered from alphanumeric to alphanumeric plus underscore, then you can restore the sense of the grep by writing
my $mismatch = grep /\W/, $full_name, $user_name, $password, $new_password
which will set $mismatch to a positive true value if any of the values contains a "non-word" character, which is alphanumeric plus underscore as you wanted.
However, the problem you are seeing
Use of uninitialized value $_ in pattern match (m//)
is because at least one of the parameters $full_name, $user_name, $password, or $new_password is undefined. You need to find out which one and why it is happening. Are you sure that all four query parameters full_name, user_name, password, and new_password are present in the query string you're getting back? Take a look at what the query_string method returns to see.
Well, "use of initialized value" isn't an error, it's just a warning. More recent versions of Perl will tell you which variable is causing the problem.
Are you sure that it's the grep line that is generating the errors? Are you sure that you are filling in all of the form inputs when you're testing this?
The following suggestions, don't address your warning. But they are problems with your code.
The regex you are using for your grep seems broken. Your code says "set $missing to the number of variables that include nothing but alphanumeric characters". That will be set to four if you get four alphanumeric-only inputs. You then trigger the error page - which seems to be the inverse of what you want. Your regex also checks for zero or more alphanumeric characters. So it accepts the empty string. Is that what you want?
Also, your regex is too complicated. There's no need to include both A-Z and a-z if you're using /i to make the match case-insensitive. In fact your regex can be collapsed to /^\w*$/i (as \w means "alphanumeric characters plus an underscore").
Checking that inputs only contain alphanumeric characters is probably a bad idea as well. Most people's full names will include at least one space. And limiting passwords to just containing alphanumeric characters is a terrible idea.
When people point out that CGI is no longer recommended, that doesn't mean that you should go back to using Matt Wright's broken CGI parameter parser from twenty years ago. That code is just as broken as it always was. No-one should be using it. You should be looking at one of the modern Perl web development frameworks that are based on PSGI - something like Web::Simple, Dancer or Mojolicious. See CGI::Alternatives for details.

What is the issue with this CGI/HTML/Perl program? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am using XAMMP Apache Server. There is a text file named 'animal.txt' containing the name of an animal on each line, with a basic description.
I am trying to write a Perl program, using HTML and CGI. The aim of the program is to have the user search an animal name, using a HTML form. This will then link to a Perl program which loops through the animal.txt file and reads the file line by line. The program will take any line that matches the users search from the original HTML form, and print all animals containing the same name.
So far this is where I am :
(Clientside form)
#!\xampp\perl\bin\perl.exe
use CGI qw/:standard/; # load standard CGI routines
use CGI::Carp('fatalsToBrowser');
print header(); # create the HTTP header
print <<HTML
<head>
<title>Shop Here</title>
</head>
<body>
<h1>Animal list search</h1>
A basic form <br />
<form action="dumpsVar2.pl">
Search: <input type="text", name="Search" size=5><br><br>
Submit: <input type="submit" name="select" size="7"><br>
</form>
</body>
</html>
HTML
And then the perl program: (Server-Side)
#!\xampp\perl\bin\perl.exe
use CGI qw(:standard);
use CGI::Carp('fatalsToBrowser');
$query = new CGI;
#parameters = $query -> param;
print header, start_html("Parameters");
print "$0 was passed these parameters:<br> <br> ";
foreach $name (#parameters) {
$value = $query -> param($name);
print p("$name = $value");
}
$inFile = "animal.txt";
open (IN, $inFile) or die "Can't find file: $inFile";
#animals = (<IN>);
$item = param;
foreach $line (<IN>) {
if ($line =~ /$item/) {
print "$item";
}
}
print end_html;
Several issues here, but the crux of the matter is this code.
#animals = (<IN>);
$item = param;
foreach $line (<IN>) {
if ($line =~ /$item/) {
print "$item";
}
}
Let's look at each line in turn:
#animals = (<IN>);
This reads all of the data from IN into the array #animals. It also leaves IN's file pointer at the end of the file. Any further attempts to read data from IN will fail.
$item = param;
If you call param with no arguments, you get a list of the parameter names that were found in the CGI request. As you're assigning this list to a scalar value, this behaviour changes and you'll get the number of parameters. In your system this will always be 1. So $item contains the value 1.
foreach $line (<IN>) {
Remember how you read all of the data from IN a couple of lines back? Well you're trying to read more data from it here. And that's not going to work. I think you probably wanted #animals here, not <IN>. Currently your foreach is never executed as on the first iteration the call to <IN> returns undef - which is false.
if ($line =~ /$item/) {
Let's assume that you've replaced <IN> with #animals in your foreach loop - so that the loop body is actually executed. This still isn't doing what you wanted. Remember that $item contains 1 rather than the name of an animal to search for. And I doubt that you have an animal called "1".
What you probably want is something more like this:
my $animal = param('Search');
while (<IN>) {
print if /$animal/;
}
I'd also point out that learning CGI in 2014 is pretty ridiculous. You would be far better off looking at a simple Perl web framework like Web::Simple or Dancer.
I think your problem is
$item = param;
Which is putting the number of parameters in your form, in this case 2, into $item. I doubt you have an animal named 2
Change it to
$item = param('Search');

Perl param() receiving from its own print HTML

I have a Perl script that reads in data from a database and prints out the result in HTML forms/tables. The form of each book also contains a submit button.
I want Perl to create a text file (or read into one already created) and print the title of the book that was inside the form submitted. But I can't seem to get param() to catch the submit action!
#!/usr/bin/perl -w
use warnings; # Allow for warnings to be sent if error's occur
use CGI; # Include CGI.pm module
use DBI;
use DBD::mysql; # Database data will come from mysql
my $dbh = DBI->connect('DBI:mysql:name?book_store', 'name', 'password')
or die("Could not make connection to database: $DBI::errstr"); # connect to the database with address and pass or return error
my $q = new CGI; # CGI object for basic stuff
my $ip = $q->remote_host(); # Get the user's ip
my $term = $q->param('searchterm'); # Set the search char to $term
$term =~ tr/A-Z/a-z/; # set all characters to lowercase for convenience of search
my $sql = '
SELECT *
FROM Books
WHERE Title LIKE ?
OR Description LIKE ?
OR Author LIKE ?
'; # Set the query string to search the database
my $sth = $dbh->prepare($sql); # Prepare to connect to the database
$sth->execute("%$term%", "%$term%", "%$term%")
or die "SQL Error: $DBI::errstr\n"; # Connect to the database or return an error
print $q->header;
print "<html>";
print "<body>";
print " <form name='book' action='bookcart.php' method=post> "; # Open a form for submitting the result of book selection
print "<table width=\"100%\" border=\"0\"> ";
my $title = $data[0];
my $desc = $data[1];
my $author = $data[2];
my $pub = $data[3];
my $isbn = $data[4];
my $photo = $data[5];
print "<tr> <td width=50%>Title: $title</td> <td width=50% rowspan=5><img src=$photo height=300px></td></tr><tr><td>Discreption Tags: $desc</td></tr><tr><td>Publication Date: $pub</td></tr><tr><td>Author: $author</td></tr><tr><td>ISBN: $isbn</td> </tr></table> <br>";
print "Add this to shopping cart:<input type='submit' name='submit' value='Add'>";
if ($q->param('submit')) {
open(FILE, ">>'$ip'.txt");
print FILE "$title\n";
close(FILE);
}
print "</form>"; # Close the form for submitting to shopping cart
You haven't used use strict, to force you to declare all your variables. This is a bad idea
You have used remote_host, which is the name of the client host system. Your server may not be able to resolve this value, in which case it will remain unset. If you want the IP address, use remote_addr
You have prepared and executed your SQL statement but have fetched no data from the query. You appear to expect the results to be in the array #data, but you haven't declared this array. You would have been told about this had you had use strict in effect
You have used the string '$ip'.txt for your file names so, if you were correctly using the IP address in stead of the host name, your files would look like '92.17.182.165'.txt. Do you really want the single quotes in there?
You don't check the status of your open call, so you have no idea whether the open succeeded, or the reason why it may have failed
I doubt if you have really spent the last 48 hours coding this. I think it is much more likely that you are throwing something together in a rush at the last minute, and using Stack Overflow to help you out of the hole you have dug for yourself.
Before asking for the aid of others you should at least use minimal good-practice coding methods such as applying use strict. You should also try your best to debug your code: it would have taken very little to find that $ip has the wrong value and #data is empty.
Use strict and warnings. You want to use strict for many reasons. A decent article on this is over at perlmonks, you can begin with this. Using strict and warnings
You don't necessarily need the following line, you are using DBI and can access mysql strictly with DBI.
use DBD::mysql;
Many of options are available with CGI, I would recommend reading the perldoc on this also based on user preferences and desired wants and needs.
I would not use the following:
my $q = new CGI;
# I would use as so..
my $q = CGI->new;
Use remote_addr instead of remote_host to retrieve your ip address.
The following line you are converting all uppercase to lowercase, unless it's a need to specifically read from your database with all lowercase, I find this useless.
$term =~ tr/A-Z/a-z/;
Next your $sql line, again user preference, but I would look into sprintf or using it directly inside your calls. Also you are trying to read an array of data that does not exist, where is the call to get back your data? I recommend reading the documentation for DBI also, many methods of returning your data. So you want your data back using an array for example...
Here is an untested example and hint to help get you started.
use strict;
use warnings;
use CGI qw( :standard );
use CGI::Carp qw( fatalsToBrowser ); # Track your syntax errors
use DBI;
# Get IP Address
my $ip = $ENV{'REMOTE_ADDR'};
# Get your query from param,
# I would also parse your data here
my $term = param('searchterm') || undef;
my $dbh = DBI->connect('DBI:mysql:db:host', 'user', 'pass',
{RaiseError => 1}) or die $DBI::errstr;
my $sql = sprintf ('SELECT * FROM Books WHERE Title LIKE %s
OR Description LIKE %s', $term, $term);
my $sth = $dbh->selectall_arrayref( $sql );
# Retrieve your result data from array ref and turn into
# a hash that has title for the key and a array ref to the data.
my %rows = ();
for my $i ( 0..$#{$sth} ) {
my ($title, $desc, $author, $pub, $isbn, $pic) = #{$sth->[$i]};
$rows{$title} = [ $desc, $author, $pub, $isbn, $pic ];
}
# Storing your table/column names
# in an array for mapping later.
my #cols;
$cols[0] = Tr(th('Title'), th('Desc'), th('Author'),
th('Published'), th('ISBN'), th('Photo'));
foreach (keys %rows) {
push #cols, Tr( td($_),
td($rows{$_}->[0]),
td($rows{$_}->[1]),
td($rows{$_}->[2]),
td($rows{$_}->[3]),
td(img({-src => $rows{$_}->[4]}));
}
print header,
start_html(-title => 'Example'),
start_form(-method => 'POST', -action => 'bookcart.php'), "\n",
table( {-border => undef, -width => '100%'}, #cols ),
submit(-name => 'Submit', -value => 'Add Entry'),
end_form,
end_html;
# Do something with if submit is clicked..
if ( param('Submit') ) {
......
}
This assumes that you're using the OO approach to CGI.pm, and that $q is the relevant object. This should work, assuming that you have $q = new CGI somewhere in your script.
Can you post the rest of the script?
I've created a mockup to test this, and it works as expected:
#!/usr/bin/perl
use CGI;
my $q = new CGI;
print $q->header;
print "<form><input type=submit name=submit value='add'></form>\n";
if ($q->param('submit')) {
print "submit is \"" . $q->param('submit') . "\"\n";
}
After the submit button is clicked, the page displays that submit is "add" which means the evaluation is going as planned.
I guess what you need to do is make sure that $q is your CGI object, and move forward from there.