Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

variables not posting?

by stuffy (Monk)
on May 03, 2001 at 09:10 UTC ( #77580=perlquestion: print w/ replies, xml ) Need Help??
stuffy has asked for the wisdom of the Perl Monks concerning the following question:

Before anyone rips me for not using CGI, I want to let it be known that I am unable to use CGI for this application due to the server I will be using it on. I am using CGI::CARP on the server I am testing it on to try to find my problems. I am trying to Post some information to the CGI, but I get a software error. It appears if I am not reading the Post correctly. The form is located stuffy's form and the code is below
#!/usr/bin/perl use CGI::Carp qw(fatalsToBrowser); read (STDIN,my($temp), $ENV{'CONTENT_LENGTH'}); my (@pairs) =split(/&/,$temp); my($item) = ""; foreach $item(@pairs) { my($key,$content) =split (/=/, $item, 2); $content=~tr/+/ /; $content=~s/%(..)/pack("c",hex($1))/ge; my($fields{$key})=$content; } print "Content-type: text/html\n\n"; print "<HTML>\n"; print "<HEAD>\n"; print "<TITLE>This is a test of the stuffy perl network</TITLE>\n"; print "</HEAD>\n"; print "<BODY>\n"; print "$fields{tool}\n"; print "$fields{month}\n"; print "$fields{date}, $fields{month}\n"; print "</BODY>\n</HTML>";
If my link did not work here is the url:
http://www.slpproductions.com/prob.html
I'm sure this is an easy problem, just something I'm overlooking. If so, please go easy on me, I'm a newbie.
Stuffy

Comment on variables not posting?
Download Code
Re: variables not posting?
by ColtsFoot (Chaplain) on May 03, 2001 at 10:43 UTC
    Always, always, always
    #!/usr/bin/perl -w use strict;
    Then USEFUL error messages are output
    I think the following modified code may help
    #!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); read (STDIN,my($temp), $ENV{'CONTENT_LENGTH'}); my (@pairs) =split(/&/,$temp); my($item) = ""; my %fields; foreach $item(@pairs) { my($key,$content) =split (/=/, $item, 2); $content=~tr/+/ /; $content=~s/%(..)/pack("c",hex($1))/ge; $fields{$key}=$content; } print "Content-type: text/html\n\n"; print "<HTML>\n"; print "<HEAD>\n"; print "<TITLE>This is a test of the stuffy perl network</TITLE>\n"; print "</HEAD>\n"; print "<BODY>\n"; print "$fields{tool}\n"; print "$fields{month}\n"; print "$fields{date}, $fields{month}\n"; print "</BODY>\n</HTML>";
    Note the declaration of my %fields before the loop
    Hope this helps
      That did help, thanks. I was wondering if somemonk could explaine why that worked, and why I needed to do that. Stuffy
        When you declare %fields inside the scope of the foreach $item (@pairs) loop with my, its contents are private to that loop. Then you try to access %fields after the loop, but it doesn't contain anything since you're outside the closing bracket (scope) of the for loop.

        -w and use strict tell of such errors.

        With your my declaration in the foreach loop you declared the hash locally.
        So the values you put into it weren't known outside.

        With using strict something like this can't happen because perl will give you an error.

        Have a look here for something more on my.
        You can also do a Super Search

Re: variables not posting?
by Xxaxx (Monk) on May 03, 2001 at 11:40 UTC
    I'm sure we've all done this same silly mistake. At least I've done my share. ;-)

    Your code:

    foreach $item(@pairs) { my($key,$content) =split (/=/, $item, 2); $content=~tr/+/ /; $content=~s/%(..)/pack("c",hex($1))/ge; my($fields{$key})=$content; }
    Here you've used my inside the scope of the foreach.
    That means that as soon as you leave the scope of foreach { } the hash %fields is inaccessible. Hence the fix that was given above handles your problem.
    my (%hash); foreach $item(@pairs) { my($key,$content) =split (/=/, $item, 2); $content=~tr/+/ /; $content=~s/%(..)/pack("c",hex($1))/ge; $fields{$key}=$content; }
    This properly declares the %hash making it available in the foreach since that is inside the variables scope. And makes it available after the foreach since that's still in scope.

    If you want to make a silly mistake that I've done on occasion try:

    <code> my (%hash); foreach $item(@pairs) { my($key,$content) =split (/=/, $item, 2); $content=~tr/+/ /; $content=~s/%(..)/pack("c",hex($1))/ge; my($fields{$key})=$content; }
    Here you have one variable called 'hash' outside the foreach and a different one 'hash' inside the foreach.

    Fortunately if you are using use strict; and -w for warnings this error will be pointed out by the error checking. Probably with a 'fields' used only once possible typo type warning. Yet another good reason to use -w warnings.

    Hope this helps you understand a little of why the fix was a fix.
    Claude

Re: variables not posting?
by stuffy (Monk) on May 03, 2001 at 12:54 UTC
    Thanks to everyone that posted. It is nice to find somewhere that is willing to help new people out. Your explinations cleared things up for me. Now if I can only retain some of the wisdom that has so gratefully been passed down to me by my perl-elders. Thanks again, Stuffy
No excuses about not using CGI.pm
by merlyn (Sage) on May 03, 2001 at 18:57 UTC
    Before anyone rips me for not using CGI, I want to let it be known that I am unable to use CGI for this application due to the server I will be using it on.
    I don't buy that one. Sorry.

    If it's a recent usable version of Perl, then CGI.pm came with it.

    Even if it's not, CGI.pm is a single file. Download it, extract it from the distribution, and place it in the "current directory", likely the same place as your script, or add a use lib... directive to point to its location.

    Even if that option is not available, because they've said "your application must fit in a single file" (a ludicrous requirement, but work with me on this one), you can edit your single file as follows:

    BEGIN { ... insert contents of CGI.pm here, stopping just before the __END__ t +oken } BEGIN { CGI->import(":all"); } ... your code goes here ... my $foo = param("bar"); ... more of your code goes here ...
    There. No excuses. Use CGI.pm.

    -- Randal L. Schwartz, Perl hacker

      As a reinforcement to merlyn's message, you don't appear to be checking some parameters when your script starts. Going directly to your script produces the output attached below. I don't know what it means, but I bet you don't want the world to peek freely at this information.
      On the other hand, the weather script you've got is quite nice.
      0 0 GENERAL COMMENTS: Several times this week, and last loose t-bars were + found 1 all of which were the new style. I dont think that 1 they work and should do some testing before spending more 1 money than necessary on them...rjy 1 1 OXIDE POLISHERS: 1 ====================================================================== +========== 1 Westech401 - 1 Westech402 - *****SHUTDOWN-NOT IN PRODUCTION***** 1 Westech403 - *****SHUTDOWN-NOT IN PRODUCTION***** 1 Westech404 - *****SHUTDOWN-NOT IN PRODUCTION***** 1 Westech409 - 1 Westech410 - 1 Westech411 - 1 Westech412 - 1 Westech413 - 1 Westech414 -failing for range, t-bar was loose as a goose, tightene +d 1 down and requaled, mesh style screen was also clogged.. +.dwh 1 1 Westech415 - 1 Westech416 - 1 Westech417 - 1 Westech418 - 1 Westech419 -failing for qual, running conditons...rjy 1 Westech420 -failing range all day, recalibrated the back pressure, 1 rebuilt carreir, replaced the pad, and ened up placing the golden 1 carrier on and the qual 1 1 Also found the screen was very clogged, had to take 1 it off to get it cleaned out. dwh 1 ***WESTECH421 IS A GOLDEN TOOL-PLEASE MONITOR CAREFULLY AND FOLLOW DY +C PLAN*** 1 Westech421 -failing for qual, rebuilt the carrier, refailing for 1 qual, changed the pad and running conditons...rjy 1 1 Westech423 - failing qual for range, checked and reinstalled t-bar 1 and it passed but failed tw for range an hour later. 1 Found drive plate was sticking to the t-bar, changed 1 it and it passed. dwh 1 1 0 0 Westech405 - 1 Westech406 - 1 Westech407 - 1 Westech408 - 1 Westech422 -adjusted the wafer sensor map for load cass...rjy 1 Westech426 - 1 1

      Furthermore, if you don't like looking at all that scary stuff at the beginning of your script, you can place those BEGIN { } code blocks at the end of your script. Won't make a whiff of difference, it'll run just the same.

      Randal is right, heed his advice.


      --
      g r i n d e r
        Not quite. The import can import prototypes, which need to sucked in before the rest of the code is compiled. Maybe not true for CGI.pm in particular, but I like to show a general template that can be copied for other problems without fear.

        -- Randal L. Schwartz, Perl hacker

      Thank you for the post. I never knew that modules could be run in a script. That is good information to have. I tried to install it in my directory, but that for some reason didn't work. I also didn't know that all you have to do is place the file in the directory. I thought that the install program had to be run. I will modify my script to use CGI.pm when I have time to work on it again.

      Stuffy

      Some people (I for one) like to learn how things work instead of using a module to do the work for them (Others I can't vouch for :P). I'm currently writing an IRC bot in perl and I *could* have used Net::IRC but I wanted to be able to write my own code and my own functions and frankly, I just wanted to learn how IRC worked on a client to server basis (After reading rfc2812). Not saying using modules is bad, but some people might like to learn how stuff works before having a module do it for them. -stormgard
        Comments should be directed towards stormgard since I was the one who wrote the above (I forgot I wasn't logged in).
(Ovid - hand-rolled CGI review) Re: variables not posting?
by Ovid (Cardinal) on May 03, 2001 at 20:15 UTC

    stuffy claimed:

    Before anyone rips me for not using CGI, I want to let it be known that I am unable to use CGI for this application due to the server I will be using it on.

    Okay, I'm an idiot and I know better, but I'll bite. What is so different about your server that you can't use a standard module that's virtually guaranteed to already be present?

    Also, you do know that your CGI form processing code is so riddled with bugs as to be virtually useless, right? Let's go through your code line by line:

    1. read (STDIN,my($temp), $ENV{'CONTENT_LENGTH'}); 2. my (@pairs) =split(/&/,$temp); 3. my($item) = ""; 4. foreach $item(@pairs) { 5. my($key,$content) =split (/=/, $item, 2); 6. $content=~tr/+/ /; 7. $content=~s/%(..)/pack("c",hex($1))/ge; 8. my($fields{$key})=$content; 9. }
    1. Line 1: Only does POST, not GET.
    2. Line 1: Why don't you check to see if the read was successful?
    3. Line 1: You don't verify that the amount of data read is the same as $ENV{'CONTENT_LENGTH'}.
    4. Hmm... three problems and we're still on the first line

    5. Line 2: The semicolon is an alternate delimeter. An agent submits data using that and your code breaks. Of course, since you can't guarantee that the data in $temp isn't corrupt...
    6. Line 3: Misplaced. $item should be scoped in the for loop:

      for my $item ( @pairs ) {

    7. Line 4: See line 3 comment above.
    8. Line 5: If an equals sign is submitted in form data, it is encoded as %3D to avoid clashing with the name/value pair delimiter. Therefore, the third argument to split is superfluous (though I admit that I'm just nitpicking now).
    9. Line 6: What about the key? Spaces are allowed in the keys, also. If you say, "yeah, but this is only for my forms", than you deliberately limit all future programs you write because you didn't bother to address this now. Don't forget to think about what you might need to use this for later.
    10. Line 7: See line 6 comment above.
    11. Line 8: Did you know the query string color=red&color=blue is quite valid? You code breaks on that.
    12. Line 9: I can't find a problem with this line.

    I don't mean to come across as harsh, but this is the reason why people say "don't hand-roll this stuff!" Read what merlyn wrote about how to get use CGI.pm when it's not allowed on your server.

    Just looking at your code, one can tell that you have some basic programming issues to learn (sanity checking, scoping, the benefits of strict, etc). Do you really assume that your code snippet is superior to the collective wisdom of thousands of programmers the world over?

    I realize that you said you were a newbie. Here's my confession: when I was a newbie, I also preferred to "roll my own." It took a lot of time for me to get over my basic stubborness and see the error of my ways. But let's keep this last paragraph between us, shall we? ;-)

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

      Line 2: The semicolon is an alternate delimeter. An agent submits data using that and your code breaks. Of course, since you can't guarantee that the data in $temp isn't corrupt...

      I'd like to see some evidence.

      Of the various good arguments for using CGI.pm, this one has always struck me as the weakest. The use of a semicolon as an argument delimeter is so effectively deprecated as to be non-existent. When is the last time you heard of any agent using a semicolon as a delimeter (other than a hand-rolled agent whose purpose is to demonstrate that it can be done)? What browsers use a semicolon?

      I know of a few public web-based systems that have run for years without encountering a semicolon used as a parameter delimeter. Is that proof that such a thing can never happen? No. Are these systems at risk? No, unless some practical joker decides to hand-roll a request.

        It's the opposite of deprecated. It's intended to be supported in the future, so if you don't start supporting it now, browsers which use it in the future will break your code.

        -- Randal L. Schwartz, Perl hacker

      Instead of making me feel like a total looser for even trying to learn how to program in perl, would you be willing to show me how to fix those problems that do exist. I will be trying to use CGI.pm after reading merlyns post, but as for a learning referance, I would like to know how to do it the right way

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (10)
As of 2014-07-30 10:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (230 votes), past polls