http://qs1969.pair.com?node_id=152307

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

Hi,

I have just written a module that takes the QUERY_STRING var and splits it up into a hash. The only prob ive got is stricngs are not being html-decoded. Heres the script/mod i use:

#! F:\perl\bin\perl use HTTP::QueryString; print "Content-Type: text/html\n\n"; $qs = new HTTP::QueryString; $qs->parse; $keys = HTTP::QueryString::param; print $keys->{'MAIN'}, '\n';

----------------------------------------------------

# Application name: N/A # Package name: QueryString package HTTP::QueryString; # load the needed modules for this application or module: # # Here is where you will need to load all of the modules used # by this app/mod. Anything may 'use'd will not be imported # and thus not used. use vars qw( $VERSION %GLOENV %PRIENV ); # Set up the needed OO interface refs: # # Any object-orientated programming within this app/mod will # need an object identifier. Otherwise again will not be # available for this app/mod. use URI::Escape; # Setting the version number of your app/mod: # # This is your global variabe VERSION. which is used to identify # well the version of your app/mod. $VERSION = '0.1a'; # Methods: # # Whether this is an application or perl module you'll need some # methods. And here's where they go. sub new { my $pkg = shift; %HTTP::QueryString::PRIENV = @_; my $obj = \%HTTP::QueryString::GLOENV; bless $obj, $pkg; return $obj; } sub parse { my $qs = $ENV{'QUERY_STRING'}; my @qs2 = split(/&/, $qs); for( my $i=0; $i<=$#qs2; $i++ ) { my($var,$val) = split(/=/, $qs2[$i]); $HTTP::QueryString::GLOENV{$var} = $val; } foreach $var (sort(keys(%CONFIG))) { $val = $CONFIG{$var}; $val =~ s|\n|\\n|g; $val =~ s|"|\\"|g; $val = uri_unescape($val); } return 1; } sub param { return \%HTTP::QueryString::GLOENV; } # Returning true: # # If this is a perl module then you will need to uncomment the # next line 1; __END__

Anyone know whats going on? and by the way the MAIN is present when i try it.

Elfyn

Replies are listed 'Best First'.
Re: HTML Decoding
by abstracts (Hermit) on Mar 17, 2002 at 11:33 UTC
    Hello there

    Why reinvent the wheel? The CGI module does exactly what you're trying to accomplish. Here is something from the CGI docs:

    FETCHING THE PARAMETER LIST AS A HASH: $params = $q->Vars; print $params->{'address'}; @foo = split("\0",$params->{'foo'}); %params = $q->Vars; use CGI ':cgi-lib'; $params = Vars;
    So, all you need is to create a CGI object, and get the params hash:
    use CGI qw/Vars/; my %params = Vars; # now you're good to go :-)
    Or, if you really want to pass your own QUERY_STRING, do it like this:
    use CGI; my $q = new CGI($ENV{QUERY_STRING}); my %params = $q->Vars();
    Hope this helps,,,

    Aziz,,,

      Hi,

      Sorry im also going blind as i did not see that, i do mean GLOENV. The reason why im doing this my own was is because this module will go into production software and i dont think i can use CGI in production software?

        People all over the globe are using this piece of (imnsho) ugly code in production, and the module has proven to be very stable and capable.

        Let me stress the last part of Juerd's sentence. CGI.pm has been extensively tested, and is very solid. It also has a huge install base and chances are most people will have easy access to it. This is why I recommend it to new monks over creating their own buggy parsers. Those who would tell people who may be new to Perl that it's 'ugly code' are not acting responsibly. This is especially the case when they don't suggest a better alternative thereby leading some to believe that rolling their own isn't such a bad idea.

        As for your concerns with using CGI.pm in production software, are they licensing related? If so CGI.pm is licensed under the same terms as Perl, from the docs:

        This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

        I'm not a lawyer, but this would lead me to believe that there are no problems with using CGI.pm in (presumably closed source) production software. Check out the Artistic license for more information.

        So you think you can produce parsing code that works better than a module that has taken a few years to write and that has been tested by several hundred thousand programers?

        Wouldn't this qualify as a bad case of over-hubris?

        The reason why im doing this my own was is because this module will go into production software and i dont think i can use CGI in production software?

        I dislike CGI.pm, but I don't see why you couldn't use it in production software. People all over the globe are using this piece of (imnsho) ugly code in production, and the module has proven to be very stable and capable.

        U28geW91IGNhbiBhbGwgcm90MTMgY
        W5kIHBhY2soKS4gQnV0IGRvIHlvdS
        ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
        geW91IHNlZSBpdD8gIC0tIEp1ZXJk
        

Re: HTML Decoding
by gellyfish (Monsignor) on Mar 17, 2002 at 11:28 UTC

    I might be going blind but I don't see where you are setting anything in %CONFIG - did you mean to use %GLOENV instead ? Even if that were the case you aren't reassigning the unescaped value back to the hash.

    BTW Why are you re-inventing this particular wheel? There are modules on CPAN that do this, almost certainly better, and of course the CGI module already comes with recent versions of Perl - Update: abstracts explains it better in Re: HTML Decoding

    /J\

Re: HTML Decoding
by Juerd (Abbot) on Mar 17, 2002 at 12:17 UTC

    $val =~ s|\n|\\n|g;
    $val =~ s|"|\\"|g;

    No! Please do not escape your data until you need it escaped. Not always do you need those annoying backslashes there. PHP has this evil sort of auto-escapes for SQL queries mainly, but with Perl you can use DBI's excellent placeholders. Where you need it escaped, you can use quotemeta, or its interpolation shortcut \Q: "foo \Q$bar\E baz".

    foreach $var (sort(keys(%CONFIG)))

    Why sort? You're not using the new order!

    my($var,$val) = split(/=/, $qs2[$i]);
    $HTTP::QueryString::GLOENV{$var} = $val;

    That overwrites earlier set variables. This is described in great detail in Ovid's CGI course. Basically, foo=bar&foo=bar&foo=bar is a valid query string, that sets foo to three values: bar, bar and bar. You'll use this with multiple equally named checkboxes, <select multiple> and probably more.

    for( my $i=0; $i<=$#qs2; $i++ )

    Do use Perl's for (ARRAY), because it's faster and easier: for (@qs2) {

    And use strict!

    U28geW91IGNhbiBhbGwgcm90MTMgY
    W5kIHBhY2soKS4gQnV0IGRvIHlvdS
    ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
    geW91IHNlZSBpdD8gIC0tIEp1ZXJk
    

Re: HTML Decoding
by webadept (Pilgrim) on Mar 17, 2002 at 22:10 UTC
    I think you should roll your own whenever you feel you wish too and as far as this stuff about re-inventing the wheel.. well.. there are no wheels in programming. And you may come up with a better/cleaner way of doing something, or you may only improve your own spell casting level. I don't feel its over hubris, I think its just the right amount.

    Besides, why load a whole module if you only need the small hash ripper from it?? Keep on keeping on. If it gets too weird then use the CGI module and come back to it later.

    webadept
      I'm in two camps about rolling your own.

      I like to roll my own in some cases becuase I enjoy learning new stuff, and its kinda fun in a geeky way.

      OTOH there are some cases where I just wont. For example, I wouldnt even bother thinking about rolling my own CGI.pm because it has been so extensively tested.

      And then there are things which are above my skill to do at a level as well as things that are already out there.

      Of course as my skill increases, I reserve the right to change my opinions.. :-)

      I super-searched for 'recreational programming' and found the lovely old node Sins or attributes? but nothing that I would have expected to find. I checked on Google too, and now I know recreational programming isn't what I thought it was, so I guess I've missed reams of stuff about coding silly or pointless or already-done things for fun. Messing about in Perl is a great way to pass time.

      Which is not to say coding an HTML parser is a great way to pass time, but hey, knock yourself out.

      When it gets weird just enjoy the sensation. It's one of the best sensations I know. Of those I associate with programming.