
sub html でフォームに入力してもらい、
sub kekka で入力情報を確認し、
sub shori でテキストファイルに登録。
というプログラムを考えているのですが、
フォームから入力されたデータが入った変数$in{'name'}
が、sub shori に移ると消えてしまいます。
いろいろ試行錯誤したのですが分かりませんでしたので
教えていただけたらと思います。
以下がサンプルのソースです。
#!/perl/bin/perl
require './jcode.pl';
require './cgi-lib.pl';
&ReadParse;
if($in{'action'} eq "set"){&kekka;}
elsif($in{'action'} eq "sss"){&shori;}
else{&html;}
sub html{
print "Content-Type: text/html\n\n";
print <<EOM
<html>\n
<body>\n
<h1>CGIテスト1</h1>\n
<form ACTION="./sample.cgi" METHOD="POST">\n
<INPUT type=hidden name=action value="set">\n
名前<br><input type=text name="name" size="30" MAXLENGTH="30"><br>\n
<input TYPE="submit" value="確認"><INPUT type="reset" value="リセット">\n
</form>\n
</body>\n
</html>\n
EOM
}
sub kekka{
print "Content-Type: text/html\n\n";
print <<EOM
<html>\n
<body>\n
<h1>CGIテスト2</h1>\n
<form ACTION="./sample.cgi" METHOD="POST">\n
<INPUT type=hidden name=action value="sss">\n
name = $in{'name'}
<input TYPE="submit" value="登録">\n
</form>\n
</body>\n
</html>\n
EOM
}
sub shori{
print "Content-Type: text/html\n\n";
print <<EOM
<html>\n
<body>\n
<h1>CGIテスト3</h1>\n
<form ACTION="./sample.cgi" METHOD="POST">\n
name = $in{'name'}
</form>\n
</body>\n
</html>\n
EOM
}
No.4ベストアンサー
- 回答日時:
No.1 の方が、ヒアドキュメント内の変数や \n などは展開されない、と書いていますが、それは <<'EOM' のようにシングルクォートで囲んだ場合であり、<<EOM や <<"EOM" の場合には問題なく展開されます。
また、No.2 の ReadParse の指摘についても、ReadParse の引数を省略すると *in が指定されたものとして動作するので、全く問題ありません。
ちなみに ReadParse は、フォームから送信されたデータを解析して in というハッシュ(連想配列)に格納してくれます。
では何が問題かというと、kekka 画面のフォーム内に
<input type="hidden" name="name" value="$in{name}">
が無いことです。
CGI というのは1回の処理ごとに新しくプログラムが実行されるので、前回の処理で受け取った変数などは一切引き継がれません。これを引き継ぐためには HTML の hidden を利用し、フォーム送信で実行される「次回の」CGI で同じ値が設定されるようにするのです。
流れを図解すると、次のようになります。
<ブラウザ> <CGI>
アクセス ──────→ 起動
html画面 ←────── html画面を出力
: 終了
:
送信 ──────→ 起動
ReadParse で $in{name} が設定される
kekka画面 ←────── kekka画面を出力(hidden で name を埋め込む)
: 終了
:
送信 ──────→ 起動
(hiddenのname="xxx"も送信する)
name="xxx" はReadParse で解析され、
$in{name} に同じ値として設定される。
shori画面 ←────── shori画面を出力
終了
この「CGIの仕組み」は最初の内は取っ付きにくいと思いますが、何となくお分かりいただけたでしょうか?
ご返答心から感謝します。
わかりやすい解説をしていただきありがとうございます。だいたいの理屈は理解できました。
ネットや書籍で色々調べたのですが、この問題についての解説を見つけることができませんでした。ここで質問して本当に良かったです。
どうもありがとうございました。
No.3
- 回答日時:
わかりました!
sub kekka{}がおかしいです。
sub kekka{}で結果を表示させているだけで、データの再セットがされていませんので、次のsub shori{}にデータが渡っていません。
sub kekka{}に下の1文を追加してください。
<INPUT type=hidden name=name value="$in{'name'}">
再度、name=nameを宣言して、同じデータを入れて送ります。
これで、#2の
&ReadParse(*in);
も忘れずに入れておけば、動くはずです。
ご返答心から感謝します。
<INPUT type=hidden name=name value="$in{'name'}">
を追加したら変数の値が shori まで渡りました。
わかるまで考えていたただき、本当にありがとうございました。
登録フォームを作ろうと思ったのですが、この問題でつまづいて一週間以上悩んでいました。
これでなんとか作れそうです。
No.2
- 回答日時:
あ!
重要な部分が間違っています!!!
&ReadParse;
ではなく、
&ReadParse(*in);
です、(*in)が無いと、$in{'xxx'}にデータを格納できません。
もし
&ReadParse(*dat);
ならば、$in{'name'}ではなく、$dat{'name'}にデータが格納されます。
この回答への補足
ご返答心から感謝します。
&ReadParse(*in);
にしてみましたが、結果は同じでした…。
sun kekka と sub shori ではほとんど同じ処理をしており、sub html からのsubmitで移るサブルーチンが kekka であれ、 shori であれ、変数は保持されているようです。
問題は、そこから更にsubmitさせて移ったサブルーチンでは保持されていないということのようです。
そもそも根本的に何か間違っているのでしょうか…。
ちなみに、&ReadParseが何故必要なのかも分かっていないんです。すみません。
No.1
- 回答日時:
<<EOM
から
EOM
の間のhtmlのソースの出力部分ですが、この中に入っている変数や\n等は展開されません。
変数を展開するにはダブルクォーテーションで囲んで出力しないといけません。
ですので例えば、sub shori{}の中の出力部分は下記のようにすると、変数が展開されます。
print "Content-Type: text/html\n\n";
print "<html>\n<body>\n";
print "<h1>CGIテスト3</h1>\n";
print "<form ACTION=\"./sample.cgi\" METHOD=\"POST\">\n";
print "name = $in{'name'}</form>\n</body>\n</html>\n";
一応、わかりやすいように、print分を複数に分けてみましたが、1行でずらずら~っと書いても大丈夫です。
ただ、print print と沢山書くのが面倒なので、いくつかの行を纏めて書きましたが、出力はきちんと\nで改行されるので大丈夫です。
あと、"~"の中に"が発生する場合は、前に\をエスケープしておけば、単なる文字列として認識されますので"の終わりとして認識しません。
このままでは、修正とか変更の作業が繁雑なので、たとえば、出力するhtmlを別の変数に格納しておいて、必要な部分だけを置換して出力させるとか、別のファイルにしておいて、それを読み込んで加工するとか、メンテナンスを楽にすることを意識してプログラムを作るのも一つの方法です。
ところで、
<form ACTION="./sample.cgi" METHOD="POST">
name = $in{'name'}
って、おかしいと思います。
<form ACTION="./sample.cgi" METHOD="POST"name = $in{'name'}>
ではないですか?
それか、
<input type=ほにゃらら name=in{'name'}>
とか?
この回答への補足
ご返答心から感謝します。
iichihoさんの言われたとおりに、sub shori を変更してみましたがやはり変数が保持されていないようでした。
sub kekka には渡っているのですが…。
<form ACTION="./sample.cgi" METHOD="POST">
name = $in{'name'}
の部分は確かに変でした。ただ $in{'name'}の中を確かめたかっただけですので、formタグは不必要でした。
結果として sub shori のソースは
sub shori{
print "Content-Type: text/html\n\n";
print "<html>\n<body>\n";
print "<h1>CGIテスト3</h1>\n";
print "name = $in{'name'}";
print "</body>\n</html>\n";
}
でいいわけですよね?でもうまくいかないんです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- PHP PHPでCookieを使った訪問回数について 1 2023/05/28 14:10
- HTML・CSS 私の能力からして間違っていないような気がします。 4 2022/09/30 13:24
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- PHP PHPでユーザー情報を入力して簡易ログイン機能をつくってみたのですが 1 2023/05/29 08:51
- PHP PHPで画像の渡しが上手く行きません。 1 2023/02/02 09:39
- PHP 入力した部分を表示させたまま(保持)するにはどうすれば良いでしょうか? 1 2023/01/25 11:14
- PHP PHPのエラーの解消法について教えて下さい。 1 2023/02/06 10:48
- PHP PHP MySql 画像を取得 1 2022/06/04 14:05
- PHP php ログイン 1 2022/11/01 00:24
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CGI初心者です
-
Pythonのマルチプロセスでの並...
-
Perl 一定時間後にプログラムを...
-
プロトタイプ宣言のワーニング...
-
Perlでsub a($)のように$をつけ...
-
Pythonのプログラミングの質問...
-
LISPで連想配列の操作?
-
Perlで自分自身の関数名を知る...
-
JSONで文字列が長い時
-
Application.ScreenUpdating = ...
-
formで特定のinputを送信しない...
-
メモリをアドレスを直接指定し...
-
<SELECT>タグの折り返し
-
実行時エラー 3020の対策
-
【至急!!!】python言語で本を見...
-
文字の横にプルダウンを表示さ...
-
Pythonでコンソールをクリアす...
-
セレクトメニューで2つの項目...
-
sendmailで複数の宛先にメール...
-
子windowsからsubmit()後にclos...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プロトタイプ宣言のワーニング...
-
これは動いてくれますか??
-
Perlで複数の値を返す良い方法...
-
CGIから複数の別プログラムを同...
-
Rubyのgets関数について
-
dieやPerl自体でエラーが発生し...
-
Perl:計算誤差について
-
HASH(0xほげほげ)
-
内部処理形式が日付型 (Date) ...
-
引数の値をURLのパスに配列とし...
-
Perlで足し算をするには
-
Perlで自分自身の関数名を知る...
-
perlでテキスト複数行を関連付...
-
print <<"_HTML_"の中でサブル...
-
なんで?
-
Net::Telnetでタイムアウト時間...
-
foreach 回数制限
-
Pythonのマルチプロセスでの並...
-
JSONで文字列が長い時
-
Application.ScreenUpdating = ...
おすすめ情報