使用CGI处理表单数据

时间:2014-12-02 14:00:39

标签: html perl cgi

我在Perl中编程并需要从以下HTML表单中获取数据:

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

编辑:如果我不能使用CGI.pm,以下工作会怎样?

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

但每次我尝试使用这些值时都会收到错误:

 Use of unitilialized value

如何正确使用CGI处理表单数据?

编辑:我的错误可能存在于其他地方。这是我的代码。这可能是我使用grep的方式吗?我应该不使用GET方法吗?

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

2 个答案:

答案 0 :(得分:1)

您修改了我在your previous question的答案中建议的正则表达式,这是

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

您已更改它,以便$mismatch现在设置为有效的参数数量,并且无效参数集的条件现在是笨拙的{{1} }。

如果您的要求已从字母数字改为字母数字加下划线,那么您可以通过编写

恢复$mismatch < 4的意义
grep
如果任何值包含“非单词”字符,则

my $mismatch = grep /\W/, $full_name, $user_name, $password, $new_password 设置为正 true 值,该字符为字母数字加上下划线你想要的。

然而,您遇到的问题

$mismatch

是因为至少有一个参数Use of uninitialized value $_ in pattern match (m//) $full_name$user_name$password未定义。你需要找出它发生的原因和原因。您确定所有四个查询参数$new_passwordfull_nameuser_namepassword都出现在您要回复的查询字符串中吗?看看new_password方法返回的内容。

答案 1 :(得分:-1)

嗯,&#34;使用初始值&#34;不是一个错误,它只是一个警告。更新版本的Perl将告诉您哪个变量导致了问题。

您确定它是产生错误的grep行吗?当您对此进行测试时,您确定要填写所有表单输入吗?

以下建议,请勿解决您的警告。但它们是您的代码问题。

您用于grep的正则表达式似乎已被破坏。您的代码说&#34;将$missing设置为只包含字母数字字符&#34;的变量数。如果您获得四个仅限字母数字的输入,则将设置为四。然后,您将触发错误页面 - 这似乎与您想要的相反。您的正则表达式还会检查零个或多个字母数字字符。所以它接受空字符串。这就是你想要的吗?

另外,你的正则表达式太复杂了。如果您使用A-Z来使匹配不区分大小写,则无需同时包含a-z/i。事实上,您的正则表达式可以折叠为/^\w*$/i(因为\w表示&#34;字母数字字符加上下划线&#34;)。

检查输入只包含字母数字字符也可能是一个坏主意。大多数人的全名将包括至少一个空格。将密码限制为只包含字母数字字符是一个糟糕的主意。

当人们指出不再推荐使用CGI时,并不意味着你应该回到二十年前使用Matt Wright破碎的CGI参数解析器。那段代码就像往常一样破碎。没有人应该使用它。您应该看一下基于PSGI的现代Perl Web开发框架 - 类似Web :: Simple,Dancer或Mojolicious。有关详细信息,请参阅CGI::Alternatives