For Programmers: Free Programming Magazines  


Home > Archive > PERL CGI Beginners > August 2004 > Filtering CGI Variables









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Filtering CGI Variables
Bill Stephenson

2004-08-10, 3:55 am

Hi all,

I need some help. I have name/value parameters coming in from a web
form that look something like this (blank lines added for clarity):

firstname=bill
lastname=stephenson

q1=1
t1=y
d1=something 1
p1=3.45

q2=
t2=y
d2=something 2
p2=1.90

q3=
t3=y
d3=
p3=

q4=1
t4=y
d4=something 3
p4=12

q5=
t5=y
d5=
p5=

q6=3
t6=y
d6=something 4
p6=1.22

id_number=10000259
action=none

I want to remove the groups of data that look like "q3-p3" and "q5-p5"
(where "q","d", and "p" are all empty, "t" will always have data) then
re-number the groups that contain data in in at least one of the
"q","d", or "p" variables, then save them to a file that looks
something like this:

firstname=bill
lastname=stephenson

q1=1
t1=y
d1=something 1
p1=3.45

q2=
t2=y
d2=something 2
p2=1.90

q3=1
t3=y
d3=something 3
p3=12

q4=3
t4=y
d4=something 4
p4=1.22

id_number=10000259
action=none

I'm having trouble with the logic that will accomplish this. It doesn't
seem like it should be very hard to do, but I just can't seem to say it
in "perl".

Below is a script that I've been playing with that does output what I
want, but it's pretty clunky and probably not very efficient. There
must be a better way.

Thanks,

Bill Stephenson

############# start code below #############
#!/usr/bin/perl

use strict;
use CGI qw/:standard/;
use CGI::Carp('fatalsToBrowser');

# Create a new CGI Object for the form input
my $Q = new CGI;

# This represents how the app will receive data from the browser...

#print this
$Q->param('firstname' ,"Bill");
$Q->param('lastname' , "Stephenson");

#print this
$Q->param('q1' ,"");
$Q->param('t1' , "Y");
$Q->param('d1' , "12");
$Q->param('p1' , "12");

#print this
$Q->param('q2' , "13");
$Q->param('t2' , "Y");
$Q->param('d2' , "");
$Q->param('p2' , "13");

#print this
$Q->param('q3' , "16");
$Q->param('t3' , "Y");
$Q->param('d3' , "16");
$Q->param('p3' , "");

#do NOT print this
$Q->param('q4' , "");
$Q->param('t4' , "Y");
$Q->param('d4' , "");
$Q->param('p4' , "");

#print this
$Q->param('q5' , "15");
$Q->param('t5' , "Y");
$Q->param('d5' , "15");
$Q->param('p5' , "15");

#do NOT print this
$Q->param('q6' , "");
$Q->param('t6' , "Y");
$Q->param('d6' , "");
$Q->param('p6' , "");

#print this
$Q->param('q7' , "22");
$Q->param('t7' , "Y");
$Q->param('d7' , "");
$Q->param('p7' , "22");

#do NOT print this
$Q->param('q8' , "");
$Q->param('t8' , "Y");
$Q->param('d8' , "");
$Q->param('p8' , "");

#print this
$Q->param('q9' , "");
$Q->param('t9' , "Y");
$Q->param('d9' , "1000");
$Q->param('p9' , "1000");

#do NOT print this
$Q->param('q10' , "");
$Q->param('t10' , "Y");
$Q->param('d10' , "");
$Q->param('p10' , "");

#print this
$Q->param('send_email' , "yes");
$Q->param('doc_number' , "55");

# This is what we want to print...

# q1=
# t1=Y
# d1=12
# p1=12
# q2=13
# t2=Y
# d2=
# p2=13
# q3=16
# t3=Y
# d3=16
# p3=
# q4=15
# t4=Y
# d4=15
# p4=15
# q5=22
# t5=Y
# d5=
# p5=22
# q6=
# t6=Y
# d6=1000
# p6=1000
# firstname=Bill
# lastname=Stephenson
# send_email=yes
# doc_number=55

#######################################
# put all the invoice parameters names
# into an array...
#######################################
my @invoice_info = $Q->param;

# Declare some variables

my $line_counter="1";
my $row_counter="1";
my $total_rows="10";

# first we print the numbered rows that contain some data...

while ($line_counter < $total_rows) {

my $quantity=$Q->param("q$line_counter");

my $tax=$Q->param("t$line_counter");

my $description=$Q->param("d$line_counter");

my $unit_price=$Q->param("p$line_counter");


if ($quantity eq "" && $description eq "" && $unit_price
eq "") {

# do nothing

}

else {

print "q$row_counter=$quantity\n";
print "t$row_counter=$tax\n";
print "d$row_counter=$description\n";
print "p$row_counter=$unit_price\n";

$row_counter++;

}

$line_counter++;

} # end while loop


# reset the line counter...

$line_counter="1";


# Then we get all the other parameters that are not numbered rows of
data.

foreach my $invoice_item (@invoice_info) {

my $value = $Q->param($invoice_item);


if ($invoice_item eq "q$line_counter") {

next;

}

if ($invoice_item eq "t$line_counter") {

next;

}


if ($invoice_item eq "d$line_counter") {

next;

}


if ($invoice_item eq "p$line_counter") {

next: # <- Notice this is not a semi-colon ";"
# It is a colon ":". It will not work with a semi-colon ";".
# I don't know why.

}


else {

print "$invoice_item=$value\n";

next;

}


$line_counter++;


} # end foreach loop

############# end code #############

Bob Showalter

2004-08-10, 3:55 am

Bill Stephenson wrote:
> Hi all,
>
> I need some help. I have name/value parameters coming in from a web
> form that look something like this (blank lines added for clarity):
>
> firstname=bill
> lastname=stephenson
>
> q1=1
> t1=y
> d1=something 1
> p1=3.45
>
> q2=
> t2=y
> d2=something 2
> p2=1.90
>
> q3=
> t3=y
> d3=
> p3=
>
> q4=1
> t4=y
> d4=something 3
> p4=12
>
> q5=
> t5=y
> d5=
> p5=
>
> q6=3
> t6=y
> d6=something 4
> p6=1.22
>
> id_number=10000259
> action=none
>
> I want to remove the groups of data that look like "q3-p3" and "q5-p5"
> (where "q","d", and "p" are all empty, "t" will always have data) then
> re-number the groups that contain data in in at least one of the
> "q","d", or "p" variables, then save them to a file that looks
> something like this:
>
> firstname=bill
> lastname=stephenson
>
> q1=1
> t1=y
> d1=something 1
> p1=3.45
>
> q2=
> t2=y
> d2=something 2
> p2=1.90
>
> q3=1
> t3=y
> d3=something 3
> p3=12
>
> q4=3
> t4=y
> d4=something 4
> p4=1.22
>
> id_number=10000259
> action=none
>
> I'm having trouble with the logic that will accomplish this. It
> doesn't seem like it should be very hard to do, but I just can't seem
> to say it in "perl".


[snip code]

Here's the approach I would take (not tested!)

my %data;
for (param()) { # loop through all parameters
if (/^([qtdp])(\d+)$/) {
my $prefix = $1;
my $num = $2;
$data{$num}{prefix} = param($_);
}
}

Basically, this inverts the data so you have a hash like:

(
'1' => { q => 1, t => 1, d => 'something 1', p => 3.45 },
'2' => { q => '', t => 2, d => 'something 2', p => 1.90 },
... and so on
}

Now, let's find the groups that have something in q, d, or p:

my @groups = grep "@data{$_}{qw/q d p/}" =~ /\S/, sort { $a <=> $b } keys
%data;

Now you can write those groups out, renumbering as you go:

my $n = 0;
for my $g (@groups) {
$n++;
print "$_$n $g->{$_}\n" for qw/q t d p/;
}
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com