(Ovid -- bug in your hand-rolled CGI code) Re: Pushing w/ an associative array?
by Ovid (Cardinal) on Dec 27, 2000 at 21:17 UTC
|
Partly to join the chorus, I have to say "USE CGI.PM"!!! You don't want to do this on your own. In fact, you have a bug in the small snippet that you have posted -- well, you might have corrected for the bug elsewhere, but I have seen this so many times that I'm willing to wager a large sum of money that you haven't: you don't check to ensure that the length of data read from STDIN is the same as $ENV{'CONTENT_LENGTH'}
What happens if the user hits the "stop" button on their browser? What if they have a power failure? What if the Web server screws up? For any of these and other conditions, the data that you read may be corrupted and you need to verify that it's not by checking its length. Pardon me for seeming pedantic, but a good programmer looks both ways before crossing a one-way street.
If you'd like to learn more about the pitfalls of this, you can check out this link where I disect "hand-rolled" CGI parsers. I go into quite a bit of detail and by the time you're done reading it, you should have a good idea why writing your own is likely to have problems. Or, at the very least, you'll have a better idea of how to write your own (but I wouldn't recommend it -- you won't catch all of the browser anomolies).
I am curious about one thing, though. Why would you want to write your own version? Were you unaware of the alternatives or were you concerned about performance? If the latter, you can also check out CGI::Lite.
Cheers,
Ovid
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats. | [reply] |
|
|
How can I read the form input with CGI.pm, then? I still need to read in each variable name and put it into an array for sorting...
| [reply] |
|
|
use CGI qw(:standard);
my %form;
foreach (param) {
my @args = param($_);
if (@args == 1) {
$form{$_} = $args[0];
} else {
$form{$_} = [@args];
}
}
--
<http://www.dave.org.uk>
"Perl makes the fun jobs fun
and the boring jobs bearable" - me
| [reply] [d/l] |
|
|
|
|
|
|
|
(jptxs) Re: Pushing w/ an associative array?
by jptxs (Curate) on Dec 27, 2000 at 21:01 UTC
|
Your best bet is to look up and use CGI as quickly as possible. Not only will it accomplish the task you ask for it will give you a whole slew of power to play with in dealing with CGI and HTML forms related issues.
Just type perldoc CGI on your server for info, or you can follow this link to the info about it here in the perlmonks own copy of the docs. Gook luck =)
"A man's maturity -- consists in having found again the
seriousness one had as a child, at play." --Nietzsche
| [reply] [d/l] [select] |
Re: Pushing w/ an associative array?
by davorg (Chancellor) on Dec 27, 2000 at 21:00 UTC
|
Use the param function from CGI.pm.
--
<http://www.dave.org.uk>
"Perl makes the fun jobs fun
and the boring jobs bearable" - me
| [reply] |
Re: Pushing w/ an associative array?
by Hrunting (Pilgrim) on Dec 27, 2000 at 21:26 UTC
|
basically, I'm opening a text file and writing whatever was input to it
And to join the chorus here ... use CGI.pm! I mean, even if you're not into all the param() stuff or the wonderful HTML abilities it has or the way it hides all the messy CGI stuff behind a very simple and intuitive interface, you can still take advantage of its save() method which does exactly what you're looking for (and, furthermore, allows you to reload that data into a CGI object if you want to at some later date). | [reply] |
Re: Pushing w/ an associative array?
by ichimunki (Priest) on Dec 27, 2000 at 22:06 UTC
|
The answer which no one is willing to give you is this:
my %pairs = split(/&|=/, $buffer);
A hash can accept an ordered list of pairs which it will assign using a KEY VAL KEY VAL scheme.
NOTE: I am only providing this answer because your method can be improved if you insist on ignoring the sound advice to use the CGI module for handling HTTP transactions. This sort of paired-list-to-hash assignment is very useful in creating arguments for subroutines, see here for more information.
Update:This post was made in the spirit of solving the problem as stated, and is a great example of why using the CGI module is better than recoding parts of it. While this solution will work for the stated problem involving key/value pairs, it will have serious problems (as pointed out below) when you have checkboxes or empty (no default values) form fields.
It will also likely break as soon as you change your form, unless you are overly restrictive in your form construction (and prohibit check boxes and enforce default values for all fields). All of this is an inefficient use of your time as a coder. Especially when working with CGI and web development, you open up a Pandora's box of problems for yourself or your clients if you do not take advantage of every well-tested solution (like CGI.pm) and get a solid understanding of the programmming you are doing before you build something that is so easily exposed for attack (that is, the web site).
| [reply] [d/l] |
|
|
And this breaks if someone hands you the perfectly legitimate string of
key1=val1&key2=val2&key3&key4&key5&key6=val6
Please stop open-coding this. Cargo cult crap that breaks. And
CGI is a pre-installed module (even if out of date)!
-- Randal L. Schwartz, Perl hacker | [reply] [d/l] |
|
|
Good point.
But look, it's great to point out the module (which I did), but is that a learning experience? Certainly CGI should be used for handling CGI, but no one answered this poor anon_monk's more general question, which was about handling lists and assigning values to hashes (and sadly, my answer assumed that we were feeding valid pairs in, something I would now know to change). Thus, this poor monk still has no idea how to write Perl to do this when there isn't a module involved. And so we'll have this really great use of modules strung together with the Perl equivalent of baby talk. This is good if the monk is going to immediately put something into production... but is this good for the personal growth of the monk?
| [reply] |
|
|
"The answer which no one is willing to give you is
this"
And the reason that no-one is willing to give this answer
is that it has fundamental flaws.
As well as the example that merlyn gives, your code
also breaks on a query string like this:
key1=val1&key2=val2a&key2=val2b
Update: D'oh! Corrected example so the values are
actually different! Thanks merlyn.
--
<http://www.dave.org.uk>
"Perl makes the fun jobs fun
and the boring jobs bearable" - me
| [reply] [d/l] |
|
|
| [reply] |
|
|
Um, even if the values are different, it doesn't really break. It just overwrites the first value for key2 with the second listed value for this. Shouldn't keys be unique if we expect them to actually be keys? How does CGI handle this exception?
| [reply] |
|
|
|
|