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 usePOST
The problem is here
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 usegrep
, like thisNow,
$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
It looks like you just need an
else
that builds a separate page.