How to get a query string from URLs - Perl


I'm not aware of how to grab the query string from the URL using Perl. I've tried a couple of ways, example:

my $qs = $ENV{'QUERY_STRING'};
my @d = split(/&/, $qs);

if ( $d[1] eq 'reports' ) {
    ... do something


use CGI;
my $q = CGI->new;
my $page = $q->param('page');

But am not getting the value of the key. Right now I'm manually placing in the query string, i.e. project.local/routes.cgi?page=reports but I get the following from the command line:

Use of uninitialized value $qs in split at ./routes.cgi line 23.
Use of uninitialized value $d[1] in string eq at ./routes.cgi line 25.

I'm not sure why this warning exists as it should just be undef if it doesn't exist?

How should I store and check a query string variable? I'm primarily using the routes.cgi script as a routes controller where all links point to i.e. <a href="project.local/routes.cgi?page=xx"> and then I process a template toolkit file and redirect to that page (good concept?)

Results of diagnostics:

Use of uninitialized value $qs in split at ./routes.cgi line 23 (#1)
    (W uninitialized) An undefined value was used as if it were already
    defined.  It was interpreted as a "" or a 0, but maybe it was a mistake.
    To suppress this warning assign a defined value to your variables.


use URI qw( );
use URI::QueryParam qw( );

my $u = URI->new($base_url);
my ($p) = $u->query_param('page');

if ( $p eq 'reports' ) { something

Man, youre fighting many days (based on your past questions) with your route.cgi. Reading thru comments and answers in your past questions, many developers already said to you: use some framework.

Now for your question(s):

Use of uninitialized value $qs in split at ./routes.cgi line 23.

Thats mean (in line, what the use diagnostics says) - the $qs variable isn't contains any value. Why the $ENV{'QUERY_STRING'}; isn't have a value is depends on your environment, but generally, you should not depend on some environment variables but on what you get from the HTTP request.

Use of uninitialized value $d[1] in string eq at ./routes.cgi line 25.

Of course, because the $qs is undefined, the split splits the nothing, and the splitted nothing is nothing too - so you get nothing to your @d array and therefore the $d[1] isn't initialised.

BTW, when you comes from the php-word (as you said in one of your questions), you should to know, than after an succesfull split of the "QUERY_STRING" at & you will get to $d[0] the value page=report and not only the report.

As @AndyLester told you, for handling URL's (getting or composing) its parts here is the URI::URL module, but you really should at least read it's description.

Ad routes: generally is better and nicer and more SEO friendly to have URLs like:

and not

So, for the "routes" don't use URL parameters, but the PATH_INFO. And this "philosophy" is already developed into many frameworks, like Poet+Mason, Mojolicious, Dancer and many others, or here are standalone modules for handling routes. (search

From my point of view, the perl web-app developemnt based on the next commands:

Install my own perl-environment (need only once)

curl -L | bash
#relog, to init the environment

perlbrew available
prelbrew install perl-5.20.0
prelbrew switch perl-5.20.0
prelbrew install-cpanm

When got my "own" perl

cpanm Poet #will install a bunch of modules
#or alternatively
cpanm Mojolicious

And from now, things are relatively easy:

cd my_development_directory
poet new myapp
cd myapp

echo 'This is my report <% localtime %>' > comps/

and you have an running perl web-application. So, point your browser to: http://localhost:5000/report and will get

This is my report Tue Jul 29 16:09:52 2014

and alongside you will get an great debug panel and much more... (see Mason & Poet manuals)

I'm still an beginner in perl development, so other more experianced perl-monks could give you better advices.