2012-02-12 1 views
1

ユーザーが資格情報を登録したいときにユーザー名が既に使用されているかどうかをチェックするcgiファイルを作成しています。ユーザー名が取得された場合は、通知することになっています。そうでなければ、元のフラットファイルに資格情報を保存します。私はforeachステートメント内で値を割り当てた変数を比較するのに問題があります。ユーザーが入力した名前と既に格納されている名前が同じ場合、変数にユーザー名を割り当てるようにforeachに指示します。私は変数を適切に割り当てていますが、単語の後には、foreachの外でこれらの変数を再度比較するように指示したいので、操作は1回だけ実行されます。ここに私の現在のコード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

私たちの友人、For-If Antipattern。 – hobbs

+0

なぜあなたは 'qw(...)'と 'qw /.../'を使用していますか? StackOverflowでの使用のために、実際には 'qw '...''、または 'qw" ... "'が推奨されます。 –

答えて

4

があるあなたは、辞書的にあなたのforeachループの内側$nametaken変数のスコープNEWを宣言している - というか、if {}ブロック内:my $nametaken = $user;

それは$nametaken変数をあなたに同じ名前を共有することがあり外側にはありましたが、完全に異なる変数で、その範囲はifです。ifを終了すると、その変数は完全に忘れられています。それに割り当てられた価値は失われます。

あなたがここにレキシカルスコープの変数についての詳細を見ることができます:

http://perldoc.perl.org/perlsub.html#Private-Variables-via-my%28%29


は戦術的にあなたの問題を解決するために、あなたは、単に内からmy宣言を削除する必要がある場合:$nametaken=$user

これを正しく実行するには、Perlの方法で問題を完全に解決する必要があります。 foreachループを使用して値がリストに含まれているかどうかを検出できますが、Perl技法では最高のものではありません。より多くの慣用的な方法は、ハッシュ検索を使用することです。字句のみforeach内で定義されるようにスコープされているため$nametakenforeachループ外の値を持っていない理由

my %users = map { ($_ => 1) } @users; # Create a hash with users being keys 
if ($users{$username}) { 
    print "$username already taken!\n"; 
} 
+0

すごく、私は自分のコードを変更し、ハッシュのルックアップを実装しました。完璧に働いた。ありがとう!もう少しハッシュセットアップを説明できますか?あなたがマップ{($ _ => 1)}を書くとき、これは何を言っていますか? – Jared

+0

@Salmonerd - できます:)別の質問にしたいと思うかもしれません - それは他のユーザーには便利かもしれない若干別個の話です – DVK

+0

@ DVK-多分、あなたはハッシュ検索を使用しようとすることに関する私の最新の質問を見ることができますログイン確認用私は彼らをよりよく理解したいと思っています。私がそれらとやろうとしていることは、私の経験レベルを上回るものです。これまでのおかげで、ありがとうございました。 – Jared

2

理由があります。


それを行うには複数の方法が常にある:

my ($nametaken) = grep { /$username/ } @users; 

if ($nametaken) { ... } else { ... } 

または単に:

if (grep { /$username/ } @users) { ... } else { ... } 

あなたはPerlで少数の一時変数を持っている場合それは通常あまりうるさいです。

+0

彼は既にループの外側に '$ nametaken'を持っていました。これは依然として重複宣言を与えます。 – cjm

+0

@cjm:Ack。それに気付かなかった。無関係な例が削除されました。 – Zaid

3
my $nametaken = $user; 

あなたはループの外で宣言$nametakenとは何の関係もありません$nametakenという名前新しい変数を作成します。

+0

それは問題でしたが、Perlや変数の範囲ではまだまだ新しいこと、そしてそれらを宣言する方法はかなり残っています。明白なことを指摘してくれてありがとう、私はそれを少しだけよく知っている私の頭を包んだと思う。 – Jared

関連する問題