• 締切済み

postで送られてきたパラメータが処理できない(perlCGI)

postで送られてきたパラメータが処理できない(perlCGI) postメソッドで送信されてきたパラメータの値によって条件分岐しようとしているのですが どうも受け取ったパラメータがハッシュ値のはずなのにハッシュ値として処理できなくて困っています。perl自体初心者なのでなにか勘違いしている可能性が高いですが、意味不明で完全に行き詰っているのでよろしくお願いします。 (送信パラメータは{"key":"1"}) #!/usr/bin/perl read(STDIN, $data, $ENV{'CONTENT_LENGTH'}); print "Content-type: text/html\n"; print "\n"; print "$data{'key'}\n"; 確認のため上のコードのようにしてみたところなにも表示されません。 しかし最後の行でprint "$data\n"; という風に帰るとkey=1といった表示が出力されます。 $dataの中身が単純な文字列になっているかと思えばそうでもなく、かといって $data{"key"}, $data{'key'}で$dataの"key"に対応する要素を取り出そうとしてもなぜかできません。 postメソッドはただの値ではなくハッシュ値ではないと送れないみたいで多いに困っています。そもそもなんで連想配列を受け取っているはずなのに処理できないのでしょうか? 心当たりがある方、よろしくお願いします。

みんなの回答

  • YkazubonY
  • ベストアンサー率30% (26/86)
回答No.5

元のフォーム画面に問題が在るのでは? <form>タグのパラメータに下記が記述されていますか? ENCTYPE="application/x-www-form-urlencoded これが無いと、read()関数で読み込むとおかしくなりますね。

  • ralf124c
  • ベストアンサー率52% (232/446)
回答No.4

CGIから受け渡されるパラメータはPOSTでもGETでも フォーム要素名1=値1&フォーム要素名2=値2&フォーム要素名3=値3&・・・フォーム要素名n=値n という形式で「&」で接続されて一気に送られてきます。 決してハッシュ(連想配列)で送られてくるわけではありません。  ブラウザのフォーム → Webサーバアプリ(ApacheやIISなど)内のCGI → CGIによって起動されるシステム内のプログラム これを標準入力バッファで受け取るのがPOSTメソッドで、環境変数で受け取るのがGETメソッドです。 この受信したデータのかたまりをそのまま扱うよりは ------------------------------- ハッシュ名{フォーム要素名1} の内容は 値1 ハッシュ名{フォーム要素名2} の内容は 値2 ハッシュ名{フォーム要素名3} の内容は 値3 ハッシュ名{フォーム要素名n} の内容は 値n ------------------------------- とハッシュに分割して扱う方が後の処理が簡単になるので専用のサブルーチン集やPerlモジュールを利用してプログラム内でハッシュに変換しているのです。 自動でそうなるわけでなく、意図的にそうするのです。 ツールを使うと動作原理が理解できないままでトラブルシューティングにもならないので以下のようなサブルーチンを組んで ## ---------------------------------------------------------ここから ## メソッド読み込み ## ---------------------------------------------------------  sub readMethod{   my %rm_in;   my $paramPost;   my @tmpPrmt = split(/&/,$ENV{'QUERY_STRING'});   foreach(@tmpPrmt){    my ($p1,$v1) = split(/=/,$_);    $v1 =~ tr/+/ /;    $v1 =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/ego;    if(exists($rm_in{$p1})){     $rm_in{$p1} .= "\t".$v1;    }else{     $rm_in{$p1}=$v1;    }   }   read(STDIN, $paramPost, $ENV{'CONTENT_LENGTH'});   my @tmpData=split(/&/,$paramPost);   foreach(@tmpData){    my ($p1,$p2)=split(/=/,$_);    $p1 =~ tr/+/ /;    $p1 =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/ego;    $p2 =~ tr/+/ /;    $p2 =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/ego;    if(exists($rm_in{$p1})){     $rm_in{$p1} .= "\t".$p2;    }else{     $rm_in{$p1}=$p2;    }   }   return %rm_in;  } ## ---------------------------------------------------------ここまで  my %ハッシュ変数名 = readMethod(); という具合に読み込んでやれば「$ハッシュ変数名{キー名}」で参照が可能となります。 ご質問の例の場合 my %hIN = readMethod(); print "Content-type: text/plain\n\n"; print $hIN{'key'}; で「1」という結果が表示されるようになります。 このサブルーチンはそんなに長いものでないので上から順序良く読んでいってください。 GETとPOSTの各メソッド処理を混在させています。 前半がGETの処理で後半がPOSTの処理です。 Web専門でないデザイナーとか俄デザイナーとかがよくフォームの要素名について配慮せずコピペなんかでダブらせているケースや、チェックボックス群をひとつで扱いたい場合があるので、その対策として「$ハッシュ変数名{キー名}=値1\t(タブ)値2\t・・・値n」となるように組んでいます。

回答No.3

> そもそもなんで連想配列を受け取っているはずなのに処理できないのでしょうか? 連想配列は受け取っていません。 自分で連想配列に作り直して下さい。 > postメソッドはただの値ではなくハッシュ値ではないと送れないみたいで この書き方から推測すると、JavaScriptのAjax関連のライブラリを利用されていると思いますが、 いきなり複雑なことをせず、 CGIはどういうものか、HTMLフォームとはどういうものかというところから、順番に勉強したほうが良いと思います。

回答No.2

どのようなフォームデータをCGIで受け取っているのかわからないのですが、 CGI.pmを使って、処理するのが簡単ですよ。 Perlのバージョンにもよりますが、多分標準装備だと思うんで「use CGI;」 って書いたら使えますよ。参考URLに詳しいです。一応例書いておきます。 CGI側の処理です use CGI; my $q = CGI->new; #項目一個につき値が一個の時の例 my $from = $q->param('from'); my $to = $q->param('to'); #項目一個につき値が複数の時の例 @past = $q->param('past'); 頑張ってください

参考URL:
http://www.futomi.com/lecture/form/cgi-pm.html
回答No.1

Perlでは $data @data %data は全て別の変数です。 スカラ変数で受け取ったPOSTの内容はsplitなどで整形しなければ、 勝手にハッシュに変換されることはありません。 環境変数は元からハッシュですが、 readでファイルハンドルにSTDINを指定しているという事は、 POSTは標準入力でしかありません。 #!/usr/bin/perl read(STDIN, $data, $ENV{'CONTENT_LENGTH'}); ##追加 @data = split(/&/, $data); foreach $pair (@data) { ($name, $value) = split(/=/, $pair); $data{$name} = $value; } ##追加終わり print "Content-type: text/text\n"; print "\n"; print "$data{'key'}\n"; ※動作チェックはしてませんw

関連するQ&A