CGI-BBS > 基礎 > その他 > リストの複数選択後の値


カレッヂ
カレッヂ


質問者 チョップ  投稿日 2/19(月) 18:41:36
こんばんは。

リスト(上からvalueを0、1、2・・・とつけている)で複数選択された場合、
値は
012
という感じで取得されますが、これを一つ一つ分割したいときに
@data=split(/\0/,$listdata);
としていました。
がしかしこの値をひとつのCGIで使いまわししようと思い、
inputのtype=hiddenで渡したところ、分割されません。
どうもこの¥コードの知識が弱いのですが、
これはどう回避できるでしょうか。

初め文字数で判断してやろうかと思ったのですが、
どうもたとえば
01
という値でも\0が数えられるらしく、文字数がこの場合3になるようです。

この辺りの謎をお教えいただければと思います。
どうぞよろしくお願いいたします。
回答者 cmMC  [削除]  投稿日 2/20(火) 17:30:14
CGI.pmやcgi-lib.plのReadParse使用時でしょうか。

>inputのtype=hiddenで渡したところ、分割されません。
↓こんな感じに書いたときですか?
<form action="foo.cgi" method="GET">
<input type="hidden" name="list" value="0">
<input type="hidden" name="list" value="1">
<input type="hidden" name="list" value="2">
<input type="submit">
</form>

質問者 チョップ  [削除]  投稿日 2/21(水) 10:19:04
はい、そうなんです。

まず前のページでリストから選択してもらいます。
たとえばそれが、地域で、北海道から沖縄まで項目があって
複数選択可の状態になっているとします。

そこで複数選択されて、
次のsample.cgi(仮にこう名付けます)のなかで

require "cgi-lib.pl";
&ReadParse
$kinmutilist = $in{"kinmuti"};

としたところ、
その$kinmutilistの値は
012
のようになってわたってくるのですが、
このときは、各値の後ろに¥0が含まれているようなのです。

そして、同じCGIでこの値を使いまわししようと思って
<form action="sampel.cgi method=past>
<input type="hidden" name="kinmuti" value="$kinmutilist">
</form>
とすると、
次に同じsampel.cgiでReadParseしても
$kinmutilistの値には\0が含まれていないようなのです。

んーこれってどうしてなんでしょうかね。

前回、わかりづらい説明で申し訳ありませんでした。
今回もわかりづらいですかね?
もしなにかわかりましたら、お教えいただければと思います。

どうぞよろしくお願いいたします。


回答者 しあわせのツボ  [削除]  投稿日 2/21(水) 11:21:43
おそらく、cgi-lib.plがヌルコードを除去しているように思われます。
cgi-lib.pl自身が\0をデリミタとして出力するので、入力値にそれがあると、それもデリミタと見なされてしまいますから(今回は逆にそれを狙いたい訳ですが)。
対処としては、
$kinmutilist =~ s/\0/適当な文字/g;
としてデリミタを\0以外にするか、
foreach (split(/\0/,$kinmutilist)) { print '<input type="hidden" name="kinmuti" value="' , "$_\">"; }
とすることで、最初に読み込んだ時のようにバラして送信させるかでしょう。
回答者 cmMC  [削除]  投稿日 2/21(水) 11:56:31
methodをGETにして
1)hiddenで書いた時に送られる文字
(きちんと%00にエンコードされているか)
2)URLに直接書いた場合cgi側で\0を認識するか
(例: http://foo.com/bar.cgi?list=a%00b%00c )
の2点を手元の環境(IE5.0)で試したところ

1)ブラウザできちんとエンコードされない
2)cgi-libでは\0をきちんと認識する
という結果でした。

cgi-libなどが悪さをしている訳ではなく、
単にブラウザ側で\0が扱えないだけでしょう。

メソッドがGETならJavascriptを使えば\0を含ませて送信可能ですが、

無難な解決策は既出の
>最初に読み込んだ時のようにバラして送信させる
だと思います。
質問者 チョップ  [削除]  投稿日 2/21(水) 14:04:40
cmMCさん、しあわせのツボさん
いろいろありがとうございました。

今回の回避法はどうせ使いまわしデータから
\0が自動に削除されてしまうのなら、
初めからリスト値を&ReadParseした後に

$kinmutilist =~ s/\0//g;

で¥0とってしまって、

@data=split(/\0/,$listdata);
をやめて文字列の長さから

$k_len=length $kinmutilist;
for($i=0;$i<$k_len;$i++){
        $w_kinmutidata=substr($kinmutilist,$i,1);
        @kinmutidata=(@kinmutidata,$w_kinmutidata);
}
という風にして分割することにしました。

なるほど、¥0以外に変換するという手もありますね。
速度的にはそっちのほうが早くなるかもしれませんね。

でもこの謎の現象がなぜでるのかが不思議だったのでなにか解ればと思ったのですが、
んーなにやら複雑ですね。

ありがとうございました。



返信(回答)する


Web裏技