sorry if the title doesn’t make much sense, I’ll explain.
I am learning Perl, which I have to use at work, so am running test programs. I am inputting data into a web form (name, age, location) and searching a MySQL database to find a match. When I search it returns any matching results printed on the screen. However, if I go back to the form and search again, knowing that the result will not be found, it just displays the last found record and I can’t quite figure out why.
Can someone help me please?
Thanks in advance.
# Read the standard input (sent by the form):
read(STDIN, $FormData, $ENV{'CONTENT_LENGTH'});
# Get the name and value for each form input:
@pairs = split(/&/, $FormData);
# Then for each name/value pair....
$db = DBI->connect($conn->DataSource(), $conn->Username(), $conn->Password()) or die "Unable to connect: $DBI::errstr\n";
foreach $pair (@pairs)
{
# Separate the name and value:
($name, $value) = split(/=/, $pair);
#replace + with space as + means space when data is collected
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
# Store values in a hash called %FORM:
$FORM{$name} = $value;
}
$query = $db->prepare("SELECT * FROM person WHERE Name = '".$FORM{'PName'}."' AND Age = '".$FORM{'Age'}."' AND Location = '".$FORM{'Location'}."'");
$query->execute();
# BIND TABLE COLUMNS TO VARIABLES
$query->bind_columns(undef, \$name, \$age, \$location);
# LOOP THROUGH RESULTS
$row = 0;
while($query->fetch())
{
push @Peeps, Person->New();
$Peeps[$row]->Name($name);
$Peeps[$row]->Age($age);
$Peeps[$row]->Location($location);
$row++;
}
$db->disconnect(); #disconnect from the db
print '<table>';
for($i = 0; $i <= $#Peeps; $i++)
{
print "<tr><td>$Peeps[$i]{'NAME'}</td><td>$Peeps[$i]{'AGE'}</td><td>$Peeps[$i]{'LOCATION'}</td></tr>";
}
print '</table>';
$db->disconnect(); #disconnect from the db
If you are using mod_perl or fastcgi where the server process is persistent over multiple requests, global variables (which you are using in your example) may not be reset between requests, but keep their old values.
In your example, this means that the next request may see the
%FORMvalues set by the earlier request, if the request happens to come to the same server process.If by adding
%FORM = ();at the top of your script fixes the problem, then this is your issue. You can verify by saying e.g.print $test++;and see if it increments.Note that this is not the real solution, I would recommend putting your real code inside a function or module and using local variables and parameters there, it is more maintainable as well. And using some of the web application frameworks available (minimally CGI.pm).
You also need to fix the SQL injection security problem, rule of thumb: Never put variables in SQL statement strings, but do something like:
$dbh->prepare("SELECT ... WHERE This = ? AND That = ?") $dbh->execute($this, $that);