Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

UBB find user id code

by LeGo (Chaplain)
on Oct 09, 2001 at 22:34 UTC ( [id://117827]=perlquestion: print w/replies, xml ) Need Help??

LeGo has asked for the wisdom of the Perl Monks concerning the following question:

in reference to this...

Well I am going to post some code. I have a subroutine that will either return the users name or a message that will say the something to the fact "NOTLOGGEDIN" as I am assuming that no one will use that user name. If they do I will adjust.

If you could check out the code and see if there are some things that you would change. Do note that this does run... if you see something that will functionally not work agian please let me know.

#!d:\perl\bin\perl.exe -w use strict; use CGI; use CGI::Cookie; my $user = &get_userid; print "<p>whoa whoa whao $user"; sub get_userid{ print "Content-type:text/html\n\n"; ##################################################### #Here are global things that might need to be changed #these will be required from another file... had to #add for coding post though ##################################################### #Where are the Members directories? my $member_dir = "../../Members/"; #what is the name of the file that list the members my $member_file ="memberslist.cgi"; ##################################################### my $file; #the concat file, used in opens my $exact_file = "noneyet"; #this is the exact member file my @user_list; #this is the users info file holds #real cookie with user name my $login; #compares variable to id my $junk_file; #junk variable my $id; #here is the cookie id my $password; #this is the password from the cookie my %cookies; #hash to hold cookies my $nli = "NOTLOGGEDIN";#my not logged in value to return if(%cookies = fetch CGI::Cookie){ if($cookies{'UserName'}){ $id = $cookies{'UserName'}->value; }else{ return "$nli"; } if($cookies{'Password'}){ $password = $cookies{'Password'}->value; }else{ return "$nli"; } }else{ return "$nli"; } $file = "$member_dir/$member_file"; open (FH, "$file") or die "Could not open $file: $!"; while(<FH>){ chomp; ($login, $junk_file) = split(/\|\!\!\|/); if ($login eq $id){ $exact_file ="$junk_file"; } } close FH; if ($exact_file eq "noneyet"){ return "$nli"; } $file ="$member_dir/$exact_file.cgi"; open (FH, "$file") or die "Could not open $file"; while(<FH>){ chomp; push @user_list, $_; } close FH; if($user_list[0] eq $id){ if($user_list[1] eq $password){ return "$user_list[0]"; }else{ return "$nli"; } }else{ return "$nli"; } }
Basically the way that UBB works (exclusively describing for this example), is that once a user post, the users name and password are stored in cookies. I grab these. Then I check to see if this person is an actual user. If not I return NOTLOGGEDIN. UBB stores the users info in a file, I get this file name from memberslist.cgi by splitting then getting user names and file names. If they match I then open the one that coincides with the cookie $id. This file has the user name and the user password. I compare these, if they match I return the user name, else NOTLOGGEDIN.

It appears that this is very simple. I could expand to NOTAUSER, FAKEPASSWORD, but for my purpose now I don't need that functionality. Maybe the next version will have that.

I understand this code could hinder the speed of the program becuase it does not break when the user is found. I have tried break but get an use strict not allowed error. Could someone help speed this up for me?

while(<FH>){ chomp; ($login, $junk_file) = split(/\|\!\!\|/); if ($login eq $id){ $exact_file ="$junk_file"; } }
Those are the types of things I am looking for help with. Much thanks. :)

LeGo

LeGo

Replies are listed 'Best First'.
Re: UBB find user id code
by chromatic (Archbishop) on Oct 09, 2001 at 23:58 UTC
    I often spell 'break' as last.

    Beyond that, there's no need to stringify variables. If you want to set $exact_file to $junk_file, just do it. (If you're relying on overloaded stringification, it may be more clear to concatenate the assignee with the empty string. Luckily, you're not doing this, so don't worry about it. ;)

    Other things... you're reading a file linewise, pushing each onto an array, and then comparing just the first two lines. Why not just read two lines?

    Beyond that, it is good style to avoid indirect method calls (CGI::Cookie->fetch is much preferable to fetch CGI::Cookie), and calling subs with a leading ampersand and no argument lists *will* eventually cause you debugging grief. Use parens. Then drop the leading ampersand, as it's unnecessary.

Re: UBB find user id code
by arturo (Vicar) on Oct 10, 2001 at 00:08 UTC

    I don't get why you're maintaining a lot of information that you're not going to use. That's a *lot* of variable declarations in there, some of which aren't needed through the whole routine. There's also a lot that can make your code more compact and elegant. Case in point:

    my %cookies; #lots more code if (%cookies = fetch CGI::Cookie) {

    Can be elegantly compacted into

    if ( my %cookies = fetch CGI::Cookie ) { }

    ( warning: these aren't entirely equivalent, but since you're only interested in %cookies within that if block, you shouldn't notice the difference here.)

    Note also that

    if (CONDITION1) { if (CONDITION2) { } }

    is equivalent to

    if (CONDITION1 && CONDITION2) { }

    IMO, the second is much easier to follow.

    The main thing you're looking for: you want to stop once you've found the right line in the "members" file. So use last -- not break ( some C coder musta misremembered) -- to break out of the loop. It's not really use strict that causes the complaint, it's the fact that the parser doesn't recognize break as a keyword, and so thinks it's a bareword, which causes strict to complain. In reality, it's a syntax error.

    while( my($login, $junkfile) = split /\|!!\|, <FH>) { if ($login eq $id) { chomp $junkfile; $exact_match = $junkfile; last; } }
    perl -e 'print "How sweet does a rose smell? "; chomp ($n = <STDIN>); +$rose = "smells sweet to degree $n"; *other_name = *rose; print "$oth +er_name\n"'
Re: UBB find user id code
by tommyw (Hermit) on Oct 10, 2001 at 00:50 UTC

    What the others said :)

    Separate the HTML output from the logic: this code has the main effect of returning a userid, and the side effect of outputing the HTML header. At some point, you won't want to do the two things together.

    Why not return undef, or '' as the not logged in value? I hope those will never match a valid userid, and also allows you to write:

    my $userid=getuserid or castigate_user;
    . Similarly, $exact_file can be treated the same way.

    Use if as a statement modifier, rather than as a test in it's own right, then the code becomes more linear, and easier to read:

    sub get_userid { my $member_dir = "../../Members/"; my $member_file ="memberslist.cgi"; return undef unless my %cookies = fetch CGI::Cookie; return undef unless $cookies{'UserName'}; return undef unless $cookies{'Password'}; my $id = $cookies{'UserName'}->value; my $password = $cookies{'Password'}->value; my $exact_file; $file = "$member_dir/$member_file"; open (FH, "< $file") or die "Could not open $file: $!"; while (<FH>){ chomp; my ($login, $junk_file) = split(/|!!|/); if ($login eq $id) { $exact_file=$junk_file; last; } } close FH; return undef unless $exact_file; $file ="$member_dir/$exact_file.cgi"; open (FH, "< $file") or die "Could not open $file"; my @user_list=(<FH>, <FH>); close FH; return undef unless $user_list[0] eq $id and $user_list[1] eq $password; return $id; }

    Finally, do you really need to have an arbitarilly named password file for every single user? Why not just store the password directly in the members.cgi file?

      I do appreciate the suggestions. I like what you have much more than what I had.

      As to your last question that is just what UBB does. That is not something that I do. It is something that seems slow for my use, but I have to work with what they have given me. Again, Thanks.

      My code as stands is now the following taking information from all of the above users. Thanks to those. This works and the subroutine will return either undef or the users id.

      #!d:\perl\bin\perl.exe -w use strict; use CGI; use CGI::Cookie; print "Content-type:text/html\n\n"; my $user = get_userid(); print "UNDEF" if($user eq undef); print "<p>whoa whoa whao $user" if($user ne undef); sub get_userid { my $member_dir = "../../Members/"; my $member_file ="memberslist.cgi"; return undef unless my %cookies = CGI::Cookie->fetch; return undef unless $cookies{'UserName'} and $cookies{'Password'}; my $id = $cookies{'UserName'}->value; my $password = $cookies{'Password'}->value; my $exact_file; my $file = "$member_dir/$member_file"; open (FH, "< $file") or die "Could not open $file: $!"; while( my($login, $junkfile) = split /\|!!\|/, <FH>) { if ($login eq $id) { chomp $junkfile; $exact_file = $junkfile; last; } } close FH; return undef unless $exact_file; $file ="$member_dir/$exact_file.cgi"; open (FH, "< $file") or die "Could not open $file"; chomp (my @user_list= (<FH>, <FH>)); close FH; return undef unless $user_list[0] eq $id and $user_list[1] eq $password; return $id; }
      LeGo

        D'oh! The point of undef is that it evaluates to false in logic statements (see the compound statement section of perlsyn). So you don't need to explicitely test against it:

        my $user = get_userid(); print "UNDEF" unless $user; print "<p>whoa whoa whao $user" if $user;
        (oh, you don't need to bracket the conditions, when they're modifiers, and unless is the equivalent of "if not")

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://117827]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (4)
As of 2024-04-19 17:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found