我一直在研究一个cgi文件,该文件将检查用户是否想要注册其凭据时是否已经使用了用户名。如果使用用户名,则应该通知他们,如果不是,则将其凭据保存到原始平面文件。我无法比较我在foreach语句中赋值的变量。我告诉foreach如果用户输入的名称与已存储的名称相同,则为变量分配用户名。我让它正确地分配变量,但在单词之后我想告诉它在foreach之外再次比较这些变量,所以操作只进行一次。这是我目前的代码
#!/usr/bin/perl
use warnings;
use strict;
use CGI qw(:standard);
use CGI::Carp qw/fatalsToBrowser warningsToBrowser/;
use Digest::MD5 qw(md5 md5_hex md5_base64);
#telling what variables are still to be used as global
our ($username, ,$user, $nametaken);
#assigning some local variables
my $username = param("username");
my $password = param("password");
my $hashpass = md5_hex($password);
print header, start_html();
#creating an array from the flatfile that usernames and passwords are stored
my @users = do { open my $fh, "<", "password.txt" or die $!; map { chomp; split /:/ } <$fh> };
#comparing the values in the array to the username entered
foreach my $user (@users) {
if ($user eq $username) {
#printing here to test if it is comparing correctly which it is
print p("$user\n");
#assigning the $user value to $nametaken so it can be compared to later
my $nametaken = $user;
#printing here to test if the variable was correctly assigned, which it is
print p("$nametaken\n");
}
}
#printing here to test if the variable was correctly assigned, which it is not printing
#so the foreach must be causing some king of issue for this variable after it is done and I don't know what that is
print p("$nametaken\n");
#Here is where I am trying to check if the username already exists and then save the user credentials if it does not
if ($nametaken eq $username) {
print p("Username already taken, Try again");
}
#As of now the else statement is running everytime and saving new user credentials even if a username is already taken
else {
open my $fh, ">>", "password.txt" or die $!;
print $fh "$username:$hashpass\n";
print p("Your account has been created sucessfully");
close $fh;
}
print end_html();
答案 0 :(得分:4)
您在$nametaken
循环内部声明了一个新的词法范围变量foreach
- 或者更确切地说,在if {}
块内:my $nametaken = $user;
它可能与您在外面的$nametaken
变量共享相同的名称,但它是一个完全不同的变量,具有if
块的范围 - 一旦退出if
,变量完全被遗忘了。无论你赋予它什么价值都会丢失。
您可以在此处查看有关词法范围变量的更多详细信息:
http://perldoc.perl.org/perlsub.html#Private-Variables-via-my%28%29
要以战术方式解决您的问题,您只需在if:my
;
$nametaken=$user
声明即可
要以Perl方式正确地执行此操作,您应该重新考虑解决问题的方法。您可以使用foreach循环来检测列表中是否有值,但它绝对不是最好的(可读性方面,有时甚至是性能方面的)Perl技术。更惯用的方法是使用哈希查找:
my %users = map { ($_ => 1) } @users; # Create a hash with users being keys
if ($users{$username}) {
print "$username already taken!\n";
}
答案 1 :(得分:3)
my $nametaken = $user;
创建一个名为$nametaken
的 new 变量,该变量与您在循环外声明的$nametaken
无关。
答案 2 :(得分:2)
$nametaken
没有foreach
循环之外的值的原因是因为它在词法范围内仅在foreach
内定义。
总有不止一种方法可以做到:
my ( $nametaken ) = grep { /$username/ } @users;
if ( $nametaken ) { ... } else { ... }
或简单地说:
if ( grep { /$username/ } @users ) { ... } else { ... }
当Perl中的临时变量较少时,通常噪声较小。