Проверка буквенно-цифровых символов и получение ввода из HTML-формы

Я новичок в программировании на Perl, и у меня есть пара проблем с компиляцией, которые я не могу решить. Моя программа получает данные из этой HTML-формы.

Вопрос. Должен ли моя форма использовать метод post или get?

<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>

Я открываю CSV-файл, записываю значение user_name в массив и выполняю ряд проверок пользовательского ввода.

Проблема №1: мне нужно проверить, что full_name, user_name, password и new_password являются буквенно-цифровыми или пробелами, но я продолжаю получать несколько ошибок, которые выглядят так:

Use of uninitialized value $full_name in string eq at Perl.pl line 33

Я не думаю, что правильно использовал CGI для получения этих значений из формы. Я также считаю, что неправильно проверяю буквенно-цифровые символы. Как я могу решить эту проблему?

Проблема №2: мне нужно перенаправить пользователя на определенную веб-страницу, если их пароли не совпадают и если имя пользователя уже занято. Я использовал мета-перенаправление, но он не делает этого успешно. Как я могу отобразить правильную страницу ошибки?

Это мой код:

#!/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;

person sofdelg    schedule 02.12.2014    source источник
comment
Слишком много вопросов. Сначала нужно убедиться, что вы правильно вводите данные. Поскольку кажется, что нет, почему вы спрашиваете об обработке данных именно сейчас?   -  person Jukka K. Korpela    schedule 02.12.2014


Ответы (1)


Это должно вас заинтересовать. Есть ряд проблем с вашим кодом, которые не мешают ему работать, но нынешняя мудрость состоит в том, чтобы вообще не использовать CGI, поэтому я буду с вами.

  • Используйте GET, если у вас нет веской причины использовать POST

  • Проблема здесь

    if(($full_name && $user_name && $password && $new_password) eq /\A[[:alnum:]]+\z/) {
    

    Вы используете логическую операцию &&, которая объединяет истину трех переменных и проверяет, равна ли она в виде строки результату сопоставления содержимого $_ с этим регулярным выражением.

    Вы должны проверить каждую из переменных по отдельности и использовать оператор привязки =~, чтобы проверить их на соответствие регулярному выражению. Также дурным тоном является использование классов символов POSIX. Я предлагаю вам использовать grep, вот так

    my $mismatch = grep /[^A-Z0-9]/i, $full_name, $user_name, $password, $new_password;
    

    Теперь $mismatch истинно, если какая-либо из переменных содержит небуквенно-цифровой символ. (Строго говоря, он устанавливается равным количеству переменных, содержащих небуквенно-цифровой символ, который равен нулю (false), если ни одна из них не имеет такого символа.)

    Тогда вы можете сказать

    if (not $mismatch) { ... }
    
  • Похоже, вам просто нужен else, который создает отдельную страницу.

person Borodin    schedule 02.12.2014
comment
Спасибо. Теперь я правильно проверяю, являются ли входные данные буквенно-цифровыми, но я продолжаю получать сообщение об ошибке Использование неинициализированного значения $_. Что-то не так с тем, как я получаю их из формы? - person sofdelg; 02.12.2014
comment
Вы неправильно поняли мое решение. Я не могу сказать, что не так, если вы не опубликуете свой новый код. Я предлагаю вам открыть новый вопрос. - person Borodin; 02.12.2014