Skip navigation.

sub Blog

return @entries;

My journey to Perl, day 1.

,

I've started delving into Perl today. Well, I spent a good share of the day to simply figure out how the heck mod_perl was supposed to work, but after some advice from nicomen, things started rolling, and soon I started digging myself down through the book and, hopefully, the understanding.

My first real WTF about Perl, when using it to improve and dynamicalize web pages, was that I didn't have any way of getting POST and GET (or rather, when the user submits a form with either POST or GET as the method) in the Perl script, as I for instance have in PHP (where I can use the arrays $_POST and $_GET).

Acknowledging this, I found a that I had to read the data from Perl's STDIN, and I found a heavy piece of script that did about this. "Heck, do I have to do this everytime I want some data?", I thought, and started digging through the code.

After fiddling with it at the end of work today, I finally got something working:

sub getPost
{
        my %_POST, $r, @parts;
        %_POST = ();
        read( STDIN, $r, $ENV{ "CONTENT_LENGTH" } );
        @parts = split( /\&/, $r);
        foreach my $p (@parts)
        {
                my($n, $v) = split( /\=/, $p);
                $v = uri_decode($v);
                $_POST{ "$n" } = $v;
        }
        return %_POST;
}


What this code does, is basically that it reads the string submitted by the form (which is of the form a=something&b=somethingelse&c=somethingelseagain). It then splits the string on "&" and then stuffs the entries splitted into an array @parts and iterates through the array of elements that looks like a=something and splits each string on "=" and puts it into the hash %_POST. An example of how it would look with my initial string example would be:
$_POST{"a"} = "something"
$_POST{"b"} = "somethingelse"
$_POST{"c"} = "somethingelseagain"


One question that might arise: What happens if the string contains "=" or "&" or other special characters? It's quite simple really; when submitting the initial form, everything's uri encoded. For instance, "=" will be shown as "%3D".

I then tried to make another script call my initial Perl module (cuddingly named HTTPerl for a poor pun and no laugh), which didn't prove to be an easy task. HTTPerl.pm, the file name of the module, must, apparently, be in one of the folders of Perl's include folders (@INC). However, getting the current folder added to there was no simple task, and I still do not know how I can do that. Apparently, most that asked on other forums stated "Hah, no, you can't", or failed miserably trying to get it working as a workaround.

In either way, I made a test script for today's work, and it's accessible from http://shael.ath.cx/test.html. Below is the entire script in its "glory". I have not included the test.html file since it is merely a form. NB! There's a bug going on for some reason; half of the time the script won't load, giving an "Server Misconfiguration Error", while the other half it runs perfectly. I am puzzled by this, as the log file says that Perl exited with this error:

[Thu Mar 19 21:01:06 2009] [error] "getPost" is not exported by the HTTPerl module\nCan't continue after import errors at /home/robert/public_html/perl/skript.pl line 2\nBEGIN failed--compilation aborted at /home/robert/public_html/perl/skript.pl line 2.\n

Any ideas to why it is like this? I am empty of ideas.

HTTPerl.pm
#!/usr/bin/perl
package HTTPerl;
use base 'Exporter';

our sub getPost
{
        my %_POST, $r, @parts;
        %_POST = ();
        read( STDIN, $r, $ENV{ "CONTENT_LENGTH" } );
        @parts = split( /\&/, $r);
        foreach my $p (@parts)
        {
                my($n, $v) = split( /\=/, $p);
                $v = uri_decode($v);
                $_POST{ "$n" } = $v;
        }
        return %_POST;
}

our @EXPORT_OK = ('getPost');
our @EXPORT = {'getPost');
1;


Skript.pl
#!/usr/bin/perl -I .
use HTTPerl 'getPost';
%_POST = getPost();
print "content-type: text/html\n\n";

print "<html><head><title>Testing the script</title></head>";
print "<style type=\"text/css\">* { font-family: Verdana; font-size: 10px; } h1 { font-size: 16px; }</style>";
print "<body><h1>Using the information</h1>";
printf("<p>Hello %s!<br />You're %d years old and you just said: '%s'.</p>", $_POST{"name"}, $_POST{"age"}, $_POST{"text"});
print "</body></html>";

Shopping.Finally back on my feet again.

Comments

Anonymous 20. March 2009, 00:50

Per writes:

Good luck on the perl journey!

Per

Aleksander Aas 20. March 2009, 09:54

vondt i hodet! slutt å skrive slemme avanserte posts!

Jess Robinson 26. March 2009, 21:17

Hi Amnith,

Welcome to the world of Perl!

I'll attempt to answer some of your questions. Though I would also point you at the many perl community sites where you can get lots of good help, for example http://www.perlmonks.org.

Perl as a language wasn't developed solely for use on the web, thus it doesn't have a lot of stuff built-in, like PHP does. It does however come with a suite of libraries for various tasks. One of them is CGI.pm, which you can use to read POST/GET data for you, and yes, even tell which one was done.

Since you're under Apache, you'll be better off using the Apache2 modules, which you should have installed as you're using mod_perl. To get the POST/GET params, write something like:

package MyHandler;

use Apache2::Const
use Apache2::Request;

sub handler {
my $requestrec = shift;
my $request = Apache2::Request->new($requestrec);
print "You did ", $r->method, "\n";
print "Params: ", join(":", $request->params);

return Apache2::Const::OK;
}

Where method will be POST or GET, and params are names of the parameters you passed. see perldoc Apache2::RequestRec and perldoc Apache2::Request.

To add more directorys to your @INC, use the mod_perl directive: PerlSwitches, in your Apache config, eg:

PerlSwitches -I/home/stas/modperl

There's a syntax typo in your HTTPerl.pm: our @EXPORT = ('getPost'); (brackets dont match)

To test if your perl files are syntactically valid, try: perl -cw <filename>

Robert Jacobsen 27. March 2009, 08:56

Thank you for an interesting and teaching post! I'll try this out when I get back from my long-weekend home with my parents! I have edited the script somewhat, whereas I stopped exporting the function (as Kristin said: I wouldn't know where the function was coming from after a while).

Again, thank you for a very enlightening post! I highly appreciate it! :smile:

Cosimo Streppone 31. March 2009, 12:59

Yes, castaway gave you a good advice.

And if you're not using mod_perl, just use CGI instead of parsing STDIN. That's pre-1995 perl... Just curious, can you tell me where you found that code?

Robert Jacobsen 10. April 2009, 21:12

Cosimo, sorry - I forgot all about this comment. I read it shortly before leaving work, and was to answer it when I got home. I got home, but never answered it.

I found that code as a part of a monster script of doom, extracted it and was like: "HEY! IT ACTUALLY WORKS!", and then started to work on a function to parse POST. I haven't gotten to work much on Perl lately. I have a project in Java coming up and it'll eat a good share of time until the beginning of May. Then, after and between some exam reading, I'll dig into Perl. :-)

How to use Quote function:

  1. Select some text
  2. Click on the Quote link

Write a comment

Comment
(BBcode and HTML is turned off for anonymous user comments.)

If you can't read the words, press the small reload icon.


Smilies

Download Opera, the fastest and most secure browser
December 2009
M T W T F S S
November 2009January 2010
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31