2012-02-11 54 views
5

我正在處理用戶登錄,並且在用戶創建部分遇到問題。我的問題是,我試圖檢查輸入的用戶名和文本文件,看看用戶名是否已經存在。我似乎無法得到它比較輸入的用戶名和我帶入的數組。我嘗試了兩種不同的方式來完成此操作。一個使用數組,另一個使用我在網上閱讀的東西,我不太明白。任何幫助或解釋將不勝感激。問題檢查用戶輸入與用戶創建的平面文件

下面是一個使用數組我試圖比較關閉的 http://codepad.org/G7xmsf3z

這裏是我的第二次嘗試 http://codepad.org/SbeqmdbG

+1

當我看到這樣的問題時,我總是會想:「用戶名應該有多類似?」即如果允許用戶名'EXample',如果'Example'被註冊?還是應該'emily'和'emily''都允許?總之,先決定規則,然後爲它制定一個子程序,遵循這些規則。 – TLP 2012-02-11 19:37:29

+1

在這裏你會遇到一個混亂註冊系統的競爭條件。您必須弄清楚如何鎖定其他進程以更新您的賬戶列表,直到您的當前程序完成執行並釋放其鎖定。鎖定文件是可行的,但不如將信息存儲在適當的數據庫中,以便爲您處理鎖定... – tadmc 2012-02-11 20:32:21

回答

2

在你的第一次嘗試,嘗試,如果環路內放:

foreach my $pair(@incomingarray) { 
    (my $name,my $value) = split (/:/, $pair); 

    if ($name eq $username) { 
     print p("Username is already taken, try again"); 
     close(YYY); 
     print end_html(); 
    } 
    else { 
     open(YYY, ">>password.txt"); 
     print YYY $username.":".$hashpass."\n"; 
     print p("Your account has been created sucessfully"); 
    close(YYY); 
    print end_html(); 
    } 
} 

在你第二次嘗試,我認爲你應該嘗試改變線:

if (%users eq $username) { 

這一個:

if (defined $users{$username}) { 
0

正如我的評論,你不應該使用平面文件來保存用戶信息。你應該使用一個合適的數據庫來爲你處理併發訪問,而不必理解和編寫如何處理所有這些問題!

如果你堅持要用一個數組,你可以使用grep(),如果它不是「過大」搜索一下:

if (grep /^$username:/, @incomingarray) { 
    print "user name '$username' is already registered, try again\n"; 
} 
else { 
    print "user name '$username' is not already registered\n"; 
} 

我看到你的代碼中的一些其他的問題。

你應該總是喜歡詞法(我)變量超過包(我們)的變量。 爲什麼你認爲(錯誤地)$ name和$ username不能是詞法變量?

你應該總是使用open()的3-arg形式,並檢查它的返回值,就像在第二個代碼示例中一樣。第一個代碼示例中的open()是很多年前的做法。

1

如上所述,有關從其他進程鎖定平面文件的問題,也存在縮放問題。您查詢的速度越慢,用戶越多。

我幾年前開始使用一個平面文件,相信我永遠不會擴展到需要真正的數據庫,也不想學習如何使用mySQL。最終在平面文件損壞和長時間查找後,我別無選擇,只能移動到數據庫。

稍後,您會發現自己希望存儲用戶首選項,並且很容易將新的字段添加到數據庫。 Flatfile最終會將每行分割成單獨的字段。

我建議你用數據庫正確地做。

+0

這是爲了學習而完成的,它也將被連接到數據庫。這就是我將在下週試圖完成的事情,但現在我只是試圖讓平面文件工作。 – Jared 2012-02-11 22:35:08

+0

即使[NoSQL](http://en.wikipedia.org/wiki/NoSQL)數據庫也會比平面文件更好。 – 2012-02-14 05:49:02