Data posted as “multidimensional array” (read into arrays: PERL)

让人想犯罪 __ 提交于 2019-12-11 09:48:02

问题


I'm using a new payment processor, and their data sheet simply says their information is posted as multidimensional array. To quote just a few of the variables:

products[x][prod_number]
products[x][prod_name]
products[x][prod_type]

** There are ten such arrays

I have discovered if the person orders 3 items, there is a variable called "item_count" which means X becomes [0],[1] and [2]

But what is the method to read in this POSTed data and separate it. Sure it's gonna be a 'foreach' loop of some sort, but what variable names I need is a mystery

For normal variables, ie get the "name/value" pairs, I use this:

use CGI qw/:standard/;

@names=param;
foreach $name(@names){
$value=param($name);
$$name=$value;
}

Any pointers?

+++++

Not sure if this is the correct way to add to this post; I'm still learning system

my question now is WHAT FORMAT is this data POSTed to STDIN etc. Or more to the point, what will it be read into. Since "products" is a single variable name, would all the data be within a single "$products" variable, or would all the data be contained within @products?


回答1:


my $num_items = $cgi->param('item_count');

my @ordered_prods;
for my $ordered_prod_num (1..$num_items) {
   my %ordered_prod;
   for my $field_name (qw( prod_number prod_name prod_type )) {
      $ordered_prod{$field_name} =
         $cgi->param("products[$ordered_prod_num][$field_name]");
   }

   push @ordered_prods, \%ordered_prod;
}

Or on second thought,

my @ordered_prods;
for my $param_name ($cgi->param()) {
   if (
      my ($ordered_prod_num, $field_name) =
         $param_name =~ /^products\[([0-9]+)\]\[(\w+)\]\z/
   ) {
      $ordered_prods[$ordered_prod_num]{$field_name} =
         $cgi->param($param_name);
   }
}



回答2:


Better way to recieve CGI Params:

Hashref:

my $params = { map { $_ => ($cgi->param($_))[0] } $cgi->param };

Straight Hash:

my %params = map { $_ => ($cgi->param($_))[0] } $cgi->param; 

Or Monk-Mode ;)

sub Vars { 
    my $q = shift; 
    my %in; 
    tie(%in,CGI,$q); 
    return %in if wantarray; 
    return \%in; 
} 



回答3:


I managed to solve how multi-dimensional arrays work by developing a little script that others might like to try. (I'm able to test this offline as I have a PERL running on my Window's PC. No doubt others can test via a similar enviroment)

Basically, I copied a "problem" from another poster about how to POST arrays, and built a script to analyse what was being sent from HTML form to server script. I then added my own decoding routine with the help of the answers posted above. In terms of "pure" programming, it's probably crude, but it can be studied stage by stage to see what's happening: (the way I prefer to work!)

 #!/usr/bin/perl
use CGI qw/:standard/;
print "content-type: text/html\n\n";
use CGI::Carp qw( fatalsToBrowser );

if (param('action') eq '1'){    # Ignore this: Simply to help demo work
&output;
}



## The form window
## Allows two people to input required "diameters"

print <<EOF;
<form method="post" action="http://www.MY-DOMAIN.com/cgi-bin/test_multi.pl">    <!--Post to your own domain-->
<input type="hidden" name="action" value="1">                   <!-- Ignore: Simply helps demo script along-->
<table>
<tr>
<td>Customer 0: Top diameter<input name="diameter[0][top]" type="text" size="5"></td>
  <td>Customer 0:Bottom diameter<input name="diameter[0][bottom]" type="text" size="5"></td>
</tr>
<tr>
  <td>Customer 1: Top diameter<input name="diameter[1][top]" type="text" size="5"></td>
  <td>Customer 1: Bottom diameter<input name="diameter[1][bottom]" type="text" size="5"></td>
</tr>
</table>
<input type="submit" value="send form">
</form>
EOF



sub output{         # Ignore fact that it's in sub-routine: Just makes demo easier
print "These are the \"name/value\" pairs as seen by the input to script,<br>ie what form sends to &lt;stdin&gt;<br><b>Note: The \"|\" symbol is added by script for clarity</b><br><br>";
@names=param;
foreach $name(@names){
$value=param($name);
print "$name=$value|";      #Visual reminder of what's happening
}

print "<hr>";

$item_count=1;                  # ONE LESS than less than total number of "levels" in HTML form, ie Customer[0], Customer[1] = 1
@field_name=('top','bottom');           # Fields as defined in form

foreach  $i($item_count){           # Loop through each of the levels, (Customer[0] and Customer[1] in this example)
    foreach $x(@field_name){        # Loop through the fields within each level ([top] and [bottom] in example)
$name=$field_name[$x];              # Places the field name[$x] in the variable "name"
$value=param("diameter[$i][$field_name[$x]]");  # The value of the array is assigned to a variable "value" 
$$name=$value;                  # The name is assigned to a variable, and given the value (ie "$top=xx" "$bottom=zz")
print "Customer $i \$$name=".$value."<br>"; # Visual reminder of what's happening
    }
# Process this loop, and do something with data before moving to next loop
# Values on first loop:  "$i = 0", "$top=xx" and "$bottom=zz" with values of the first array
# Value on second loop: "$i=1", "$top=xx" and "$bottom=zz" with values of the second array
}
print "<hr>";

# The names of "diameter", "top" and "bottom" reflect the names used in the form and would be changed to suit requirements.
# The advantage of this script is it assigns values back to single variables, 
# and avoiding getting in a muddle trying to keep track of which element of [A][B] array one is working on at any time 
}

Hope this might help others learn how the arrays work.

NB: It seems multidimensional arrays are sent in their entirety ie: diameter[0][top]=x&diameter[0][bottom]=z&diameter[1][top]=x&diameter[1][bottom]=z, complete with square brackets in pairs



来源:https://stackoverflow.com/questions/19521690/data-posted-as-multidimensional-array-read-into-arrays-perl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!