in reply to Re^4: Parse form data to database
in thread Parse form data to database

I tried to incorporate open(OUTF, "form.txt"); followed by a print OUTF for all the $FORM fields then close (OUTF); but it did not work.

It would be better if you showed us the code as it was when you tried that. Better still if you could also say exactly what you mean by "did not work". Did you include error checking on the "open" call? Do you have access to the web server's error log, so you can look up error messages that might show up there? Maybe you were trying to open a file for write access where the web server process does not have permission to do that.

Anyway, from how you described your situation and task, it sounds like this is a "web design" course that focuses on design in the technical, server-client transaction sense, rather than design in the artistic, UI-look-and-feel sense; and in that regard, it sounds like you might still be having trouble with some of the concepts. Here is what you said (reformatted slightly):

  1. Complete a form which, when submitted, calls a script that parses the data input into the form,
  2. checks a flat file to see if the User ID is present and
  3. if so, advise to select different User ID.
  4. If not found then confirm data entered.
  5. If former user does not remember password,
    • provide form requesting the user ID, and
    • on submit have password emailed to the individual, based on the email address from the flat file.

If that's all you have for a technical design spec, your problem is that you are missing a lot of essential detail for the overall transaction between client and server.

If the idea is to have a web service that allows creation of new user accounts (userid, password, name, email, postal address) as well as access to existing accounts (userid and password authentication required), then the initial page would typically have two different submit buttons: one for each action (create vs. login).

You could have those two different submit actions invoke different scripts, or you could have one script that handles both actions, and simply looks at the parameters to know which one to do for a given request.

The create action needs all the name and address info, needs to return to the preceding form if required fields are missing or if the given userid string is already taken, and otherwise (if everything is okay) needs to add the new entry to the database and return a confirmation page to the client.

The login action only needs the userid and password params, needs to validate these against the database, and if that fails, return a login form that allows the user to request an email reminder (submission of this separate form by the client only triggers an email if the given email address exists in the database); if the login succeeds, return a confirmation page (and presumably provide access to something else as well).

Do you think you can do that by Monday? I could suggest (I expect others here will) that you consider using the CGI module, but the man page for that is quite long, and you might not have time to absorb it adequately (though you might just want to spend 10 minutes skimming over it -- maybe it will help).

For "passing the course", your current handling of the cgi params etc would probably suffice -- unless the prof is a stickler for secure design. One thing that you really should think about: just because you have a form that feeds parameters to your cgi script, this does not mean that your script will only get requests from that form. You should not trust that the parameter string will always be what you would expect from the form; e.g. only accept parameters whose names match what you need from the form.

If after passing the course (or not, as the case may be) you are still interested in the technical challenge, you can move into using a real database for the user info (or at least making sure your flat-file database is "hardened" to avoid problems of concurrent access from different clients).

(minor updates to fix grammar and add clarity)

Replies are listed 'Best First'.
Re^6: Parse form data to database
by tryharder (Initiate) on May 13, 2006 at 05:19 UTC
    Thanks for the detailed breakdown of my lack of experience. No, the Prof is very basic. Get the project done to the best of our ability. Most of us are at the same confused level. As for the script not working, we don't have access to the server to review the error logs; it works or it fails and we have to stumble through the code to find out the mistakes on our own, which is near impossible if you have no real experience with coding. I know what I am asking is a lot, but then again, I also believe what I am trying to do must be fairly easy or else our Prof just enjoys seeing the class tortured. I understand I am green at this. What I really need is someone who can help me thru this hump, and give me some sense of direction. I'm not sure what more I can give, except the failed code I noted. There has to be a way to advise how to parse data to a text file that can be reviewed for previous entries. Here is the script with the open OUTF command:
    #!/usr/bin/perl print "Content-type:text/html\n\n"; read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s/\n/ /g; # replace newlines with spaces $value =~ s/\r//g; # remove hard returns $value =~ s/\cM//g; # delete ^M's $FORM{$name} = $value; } open(OUTF,">>form.txt") or dienice("Couldn't open form.txt for writing +: $!"); flock(OUTF,2); seek(OUTF,0,2); print OUTF "$FORM{'fnameRN'}|$FORM{'lnameRN'}|";<br> print OUTF "$FORM{'addr1RN'}|$FORM{'addr2RN'}|";<br> print OUTF "$FORM{'cityRN'}|$FORM{'stRN'}|";<br> print OUTF "$FORM{'zipRN'}|$FORM{'emailRN'}|";<br> print OUTF "$FORM{'uidRN'}|$FORM{'pwd1RN'}\n";<br> close(OUTF); print <<EndHTML; <html><head><title>Thank you</title></head> <body> <h2>Thank You, $FORM{'fnameRN'} $FORM{'lnameRN'}!</h2> Here is the information you provided:<p> <table width="38%" border="1" cellspacing="0" cellpadding="0"> <tr> <td>First Name: </td> <td>$FORM{'fnameRN'}</td> </tr> <tr> <td>Last Name: </td> <td>$FORM{'lnameRN'}</td> </tr> <tr> <td>Street Address1: </td> <td>$FORM{'addr1RN'}</td> </tr> <tr> <td>Street Address2: </td> <td>$FORM{'addr2RN'}</td> </tr> <tr> <td>City: </td> <td>$FORM{'cityRN'}</td> </tr> <tr> <td>State: </td> <td>$FORM{'stRN'}</td> </tr> <tr> <td>Zip: </td> <td>$FORM{'zipRN'}</td> </tr> <tr> <td>Email: </td> <td>$FORM{'emailRN'}</td> </tr> <tr> <td>UserID: </td> <td>$FORM{'uidRN'}</td> </tr> <tr> <td>Password: </td> <td>$FORM{'pwd1RN'}</td> </tr> </table> Thank you for your feedback.<p> <a href="http://matrix.csis.pace.edu/~s06-it154a-s04/register.html">Cl +ick here</a> to return to form to make any changes, OR<br> <a href="http://matrix.csis.pace.edu/~s06-it154a-s04/cgi_scripts.html" +>Click here</a> to return to the home page. </body></html> EndHTML sub dienice { my($msg) = @_; print "<h2>Error</h2>\n"; print $msg; exit; }
      Regarding this code you just posted:

      -- When you open a file for append access ( ">>file.name"), you don't need to seek to the end of the file -- you are already there. (Likewise, after you remove the "\r", you don't need to remove "\cM" -- that's a synonym for "\r".)

      -- Why do you have those  <br> tags after the print statements to the output file? Are those really in your script, or is that just an artifact of learning how to post code here at PerlMonks? If those tags are really in the code, each one is a syntax error. Get rid of them.

      -- Apropos of syntax errors, I hope that you have perl available on a local machine, so you can at least try  perl -cw your_script on the command line. This will tell you whether the code compiles, which you need to know before putting it on a server where you can't see the error logs.

      -- Is it the case that nothing ever gets written to the output file at all? Do you get the "Error" message from your "dienice" call showing up as the result? What does that say? (Permission denied? something else? This is the second time I'm asking this question...)

      As for giving you some sense of direction, I was hoping my earlier reply already did that. Writing the code for you would be wrong, but assuming that this particular script you posted is specifically for adding a new user to the database, I think a pseudo-code overview should be something like this:

      # pring http header # decode params # if required params are not present # print explanation with link to sign-up page # exit # open database file for r/w access # get lock on that file # read current contents # if userid from form exists in database # close file # print explanation with link to sign-up page # exit # print new entry fields to database file # close file # print confirmation message
      You need to make sure you add tests for error conditions with suitable calls to dienice as needed. As for the other components of the overall setup (login, password reminder), I'm hoping you can work those out in adequate detail on your own now. Good luck.
        I sense from you some slight irritation with me and my quest, and I admit I also felt was somewhat frustrated with your attitude toward my quest, though sometimes what is said in print can be misinterpretted whereas saying it verbally is much more clear. Does that make sense?
        Anyway, I actually DO appreciate the fact you were unwilling to write the code for me. I DID NOT want or expect this of anyone. How else would I learn? So, thank you! However, examples and pointers which you did provide were acceptable. It was through an examination of my script that I hoped someone would point out where I was failing in coding. You finally did that and karma will shine on you greatly for it.
        I removed the "br" tags (living in an HTML coding world caused me to incorporate that by mistake), and deleted the "\r". The script NOW does as I intended. THANK YOU for that. btw: not that it is worth it now, here is the exact verbiage of the error you pointedly noted was requested twice:

        ERROR
        This error is very likely due to a mistake in your program.
        --------------------------------------------------------------------------------
        Follow the steps below to troubleshoot your error.

        The "steps below" is a comment to contact our Prof (which we can't do since it is a major project he won't assist on at any level) and a link to our Science department, which provides substantially less information than is available in Ovid's CGI Course. I plan to go over that course in depth. So, as you can see, and which I should have explained (though you might not have listened until you saw for yourself) the "error" response is worthless. Sorry I was not more expressive sooner. I have trouble putting all the detail into print sometimes.
        Botton line, I really am grateful for your assistance. All the best to you.