- ベストアンサー
要素の上書きについて
- HTMLのフォームからCGIにデータを送り、そのデータを表示するだけのCGIを作っているのですが、HTMLフォームの中の項目を空のまま送信したときに、CGI側でその表示部分はなくなります。
- 項目が空の時には、CGIで以前に登録していたデータが上書きされずに表示されるようにしたいのですが、どうしたら良いのかわかりません。
- perl初心者です。どなたかご教授していただけないでしょうか。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは、 え~とですね、 まず、デコードする前に&で分割してからデコードしましょう。 じゃないとデータに&を含んでいたときにアレなんで。 で、デコードして sjis に変換したデータを %form にバッファしてます。 (注意)データのキーになる部分はデコードも文字コード変換もしてません。 で、データを読み込んで、 行をタブで区切って、(勝手にデータはタブ区切りにしました。) さらに最初に見つかった = の左にある文字列をキー、右側にある文字列を値として、 %form に上書きしてます。 私が追加した部分も含めて、 突っ込み所満載&他にやり方いっぱいなんですが、 とりあえず動かすためということで… #!/usr/local/bin/perl use strict; #データファイル my $datafile='./data.dat'; #ライブラリの読み込み require './jcode.pl'; my $input; #フォームデータの読み込み if ($ENV{REQUEST_METHOD} eq "POST"){ read (STDIN,$input,$ENV{CONTENT_LENGTH}); }else{ $input=$ENV{QUERY_STRING}; } #フォームデータのデコード my %form = (); my @pairs = split(/&/, $input); foreach my $pair ( @pairs ){ my( $name, $value ) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2", $1)/eg; #SJISコード変換 &jcode::convert(\$value, 'sjis'); $form{$name} = $value; } #データのオープン open(DAT,"+<$datafile"); flock(DAT, 2); #ファイル読み込み my $line = <DAT>; for ( split /\t/ , $line ) { my( $key , $value ) = $_ =~ /^(\[^=]*)=(.*)$/; #フォームデータの上書き $form{$key} ||= $value; } #データの書き込みとクローズ seek(DAT,0,0); $line = ''; while (my($key,$value) = each %form) { $line .= "${key}=${value}\t"; } print DAT $line; close(DAT); &header; print <<EOM; </body> <form action="samp.cgi" method="GET"> <input type="text" name="A" value="$form{A}"><br> <input type="text" name="B" value="$form{B}"><br> <input type="text" name="C" value="$form{C}"><br> <input type="submit" value="submit"> </form> </html> EOM exit; #----------------------------------------------------------------------------------- # HTMLヘッダー #----------------------------------------------------------------------------------- sub header { #同じ } わかんないトコは聞いて下さい。 バグが無い保証はしません。 あくまでも動かす為のやっつけ程度の物だという事でお願いします。
その他の回答 (2)
- g_p_
- ベストアンサー率53% (28/52)
こんにちは、 訂正です。 my( $key , $value ) = $_ =~ /^(\[^=]*)=(.*)$/; の\は要りません。なぜ書いたのか自分でも分かりません。 my( $key , $value ) = $_ =~ /^([^=]*)=(.*)$/; でお願いします。 あと、 print <<EOM; </body> <form action="samp.cgi" method="GET"> <input type="text" name="A" value="$form{A}"><br> <input type="text" name="B" value="$form{B}"><br> <input type="text" name="C" value="$form{C}"><br> <input type="submit" value="submit"> </form> </html> EOM でいきなり</body>はないですよね、すんません。 まだあるかもですが… >perl全般に理解が足りないよ! いやいや、実は私もまだ脱初級レベル目指してる程度です。お気楽ホビー派ですんで。 ただ、ちょっとでも役に立てばと思って暇な時ウロウロしてます。
- g_p_
- ベストアンサー率53% (28/52)
こんにちは、 以下の部分を $input が空だったら通らないようにしてみては? >#データのオープン >open(DAT,"+< $datafile"); >flock(DAT, 2); >#データの書き込みとクローズ >seek(DAT,0,0); >print DAT $input; >close(DAT); 思いっきりシンプルに書けば、 if ( $input ) { #ファイルの書き込み処理 } とか。 >perl初心者です。 余計なお世話かもしれませんが、 早くから、スクリプトの2行目に use strict; を書く癖をつけておくと、いろんな意味で良いですよ。 最初は、今まで動いていたものが動かなくなって、 いやになるかもしれませんけどね。
お礼
回答ありがとうございました。いろいろ勉強になりました。 use strict;は、もう少し勉強して知識がちゃんとしてから、使っていきたいと思います。(myとlocalの違いや使い方の理解がまだまだあやふやなので・・・perl全般に理解が足りないよ!というツッコミは、胸の中にそっとしまっておいて下さい) ただ、私の質問の仕方が悪かった事も分かりました。私の今、作っているCGIでは、大きく3つの項目(仮にA、B、C)に分かれて表示されるわけですが、初めにフォームから、CGIにデータを送り、データがCGIに全て入っている状態だとします。 A=Aのデータ B=Bのデータ C=Cのデータ 現状では、Bのデータだけ変更したいときにも、フォームA、B、Cの項目全てを埋めて送信しないとAとBの内容が空になってしまいます。これを、フォームA、Cが空白で送信された時は、もともと有ったAのデータ、Cのデータを表示する、というふうにしたいのです。 g_p_さんの回答がそれだよ!ということだと、単に私の理解力と知識のなさが原因なので、そこのところを指摘していただければありがたいです。 私の説明べたにせよ、理解力と知識のなさにせよ、回答してくれたg_p_さん、ありがとうございました!
お礼
ANo.1~3のg_p_さん! できました!ありがとうございました!!感謝感激です!! 私がすんなり書かれていることを理解して手直しできてれば、もっと早くにお礼を言えたのですが、超ど級の素人の悲しさ・・・すっごい無駄なことを繰り返していたので、お礼が遅れました。 私の要領を得ない最初の質問から、ヒントどころか答えまで出していただき、本当にありがとうございました。また、私のような超ど級の素人の為に時間を割いていただき、重ね重ねお礼を申し上げます。 ありがとうございました!!!!!!