アプリ版:「スタンプのみでお礼する」機能のリリースについて

こんにちわ。perlでCGI学んでます。初心者です。

CGIの中にヒアドキュメントでHTMLを書きました。
そのページの最後に「次のページへ」というフォームボタンをつけました。ボタンをクリックするとサブルーチンの次ページが表示されるようにしたいのですが、うまくいきません。ボタンはinputタグのボタンにしたいので、テキストリンクにはしません。

「次のページへ」をクリックするとサブルーチンのpage1の中が表示されるようにするにはどうしたらいいですか?hiddenタグをボタンの下に書けばいいといわれたのですが、どうもうまくいきません。ご存知のかた、ご教授願います。


以下のようにソースを書きましたがうまくできません。。。。

#!/usr/bin/perl

$script="test.cgi"

print <<"EOF";
Content-type: text/html

<html>
<head>
<meta content="text/html; charset=shift_jis">
<title></title>
</head>
<body>

あなたの注文したものは●●です。
よろしかったら次のページへを押してください。

<form method="post" action="$script">
<input type="submit" value="次のページへ">
<input type="hidden" name="page1" value="page1">
</form>

</body>
</html>
EOF

####サブルーチン######################
sub page1{

print <<"EOF";
Content-type: text/html

<html>
<head>
<meta content="text/html; charset=shift_jis">
<title></title>
</head>
<body>
お買い上げありがとうございました。
</body>
</html>

EOF

}

A 回答 (5件)

送信された値の取得にはCGI.pmかcgi-lib.plを使いましょう。


こちらの記事がおすすめです。

「CGI.pmを使ってみよう」
http://www.futomi.com/lecture/form/cgi-pm.html

「cgi-lib.plを使ってみよう」
http://www.futomi.com/lecture/form/cgilib.html

で、好きな変数に、
<input type="hidden" name="page" value="page1">
で指定したページ数を入れます。
CGI.pmなら

use CGI;
$q = new CGI;
$page = $q->param('page');

cgi-libなら
require "cgi-lib.pl";
&ReadParse(\%input);
$page = $input{'page'}

って感じですね。
これで、$pageに指定したページ数が入りました。

そしたら、if文で$pageに入った値をチェックして、
その値によって、使用するサブルーチンを振り分けたりするわけです。

#失礼かとは思いますが、回答に対する補足を読んでいると、質問者さんはまだここで具体的な処理方法の質問をできる段階ではないように思います。
#参考URLに初心者さん向けのperl/CGI解説サイトのアドレスをいくつか入れておきますので、訪問してみてください。

参考URL:http://www.futomi.com/, http://www.aimix.jp/cgi/, http://www.site-cooler.com/kwl/perl/, http://perl.misty.ne.jp/

この回答への補足

ありがとうございます。失礼なんてとんでもございません。初心者のためにたいへん親切に答えていただきまして感謝です。ありがとうございます。とても勉強になりました。ほかのみなさんもどうもありがとうございました!

補足日時:2005/08/10 14:24
    • good
    • 0

#2です。



my とか use とか CGI とか、これ全部普通のPerlの機能です。
use CGI; はまああれですけど、my は perl を普通に使っていれば必ず使うものです。
ちなみに my はローカル変数を宣言するときに使うもので、先ほどの場合ですと $cgi という変数をメインルーチンの中でだけ使いますよ、と宣言しています。
従って page 関数や page1 関数内では $cgi は使えません。
use CGI は CGI モジュールを使いますよ、という宣言ですね。
このモジュールを使わない方法はもちろんあります。
ですが、相当面倒です。
これはこういうものだ、と割り切って使ってしまった方が楽です。
強いて言えば#1さんがやっているようなデコード処理をするわけですが、あれを見て何をやっているのかわからないようであれば見る意味もないです。
また一から自分でデコード処理を作るよりも既に提供されているものを使ったほうが確実です。
今はこういう宣言をすると $cgi->param("xxx") でフォームの値が取得できるんだ、ということがわかっていればよろしいかと思います。
まずはフォームからの入力処理等一連の処理を作れるようになってから勉強しても遅くはないと思います。
    • good
    • 0

モジュールなしバージョンです。




#!/usr/bin/perl

$script="test.cgi"

$buffer = &get_buffer();
%FORM = &get_value($buffer);

$mode = $FORM{'page1'};
if ($mode eq 'page1') { &page1(); }
else { &top(); }

exit;

sub top {
print <<"EOF";
Content-type: text/html

<html>
<head>
<meta content="text/html; charset=shift_jis">
<title></title>
</head>
<body>

あなたの注文したものは●●です。
よろしかったら次のページへを押してください。

<form method="post" action="$script">
<input type="submit" value="次のページへ">
<input type="hidden" name="page1" value="page1">
</form>

</body>
</html>
EOF
}

####サブルーチン######################
sub page1{

print <<"EOF";
Content-type: text/html

<html>
<head>
<meta content="text/html; charset=shift_jis">
<title></title>
</head>
<body>
お買い上げありがとうございました。
</body>
</html>

EOF

}

#-------------------------
# $buffer取得
#-------------------------
sub get_buffer {

# フォームデータ取得
if ($ENV{'REQUEST_METHOD'} eq "POST") {read(STDIN, $tmp, $ENV{'CONTENT_LENGTH'}); }
else { $tmp = $ENV{'QUERY_STRING'}; }

return($tmp);
}

#-------------------------
# $buffer分解
#-------------------------
sub get_value {

@pairs = split(/&/,$_[0]);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/\n//g;
$form{$name} = $value;
}
return(%form);
}
    • good
    • 0

プログラムの先頭でどのページを表示させるのかという処理をしなければいけません。


つまり hidden の page1 が page1 であれば page1 をコールし、違っていれば最初のページを表示させるということになります。
ではフォームの値を受け取るにはどうしたらいいか。
CGIモジュールを使うと便利です。
以下、修正したプログラムを載せます。

#!/usr/bin/perl

use CGI;

$script="test.cgi"

my $cgi = CGI->new();
if( $cgi->param( "page1" ) eq "page1" ){
&page1;
} else {
&page;
}

sub page{
print <<"EOF";
Content-type: text/html

<html>
<head>
<meta content="text/html; charset=shift_jis">
<title></title>
<style>BODY {FONT-FAMILY: arial,sans-serif}
TD {FONT-FAMILY: arial,sans-serif}
A {color:black; text-decoration:none;}
P {FONT-FAMILY: arial,sans-serif}
</style></head>
<body bgcolor="#FFFFFF" >

あなたの注文したものは●●です。
よろしかったら次のページへを押してください。

<form method="post" action="$script">
<input type="submit" value="次のページへ" style="background-color: #FFFFFF;border-color: #FFFFFF;border-style:solid;cursor:pointer;" >
<input type="hidden" name="page1" value="page1">
</form>

</body>
</html>
EOF
}

####サブルーチン######################
sub page1{

print <<"EOF";
Content-type: text/html

<html>
<head>
<meta content="text/html; charset=shift_jis">
<title></title>
<style>BODY {FONT-FAMILY: arial,sans-serif}
TD {FONT-FAMILY: arial,sans-serif}
A {color:black; text-decoration:none;}
P {FONT-FAMILY: arial,sans-serif}
</style></head>
<body bgcolor="#FFFFFF" >
お買い上げありがとうございました。
</body>
</html>

EOF

}

とこんな感じになります。
ただ hidden の ID が page1 というのはいただけません。
できれば page として value を 1 という風に、page に表示させたいページ番号を指定するという風にしたほうが汎用的です。
つまり hidden の箇所は、

<input type="hidden" name="page" value="1">

こうなり、冒頭の処理はこうなります。

if( $cgi->param( "page" ) == 1 ){
&page1;
} else {
&page;
}

こうしておけば、例えば表示するページが2ページ、3ページと増えてもわかりやすいと思います。

if( $cgi->param( "page" ) == 1 ){
&page1;
} elsif( $cgi->param( "page" ) == 2 ) {
&page2;
} elsif( $cgi->param( "page" ) == 3 ) {
&page3;
 :
 :
 :

この回答への補足

下の方もそうですが、とても丁寧に答えてくださってありがとうございます。こぴぺしたらうまく動きました!ありがとうございます!

ただ・・えー、わたしは初心者なので,useとかmyとか
$cgi->とかがよくわかりません。これがCGIモジュールというやつですよねたしか。便利ということは聞いたことがありますので、将来的には勉強しようと思っていますが、今の時点のわたしの力では無理です^^普通のperlだけでいっぱいいっぱいですから^^

myとかuseとか使わないでやる方法でできる方法があったら教えてください。
わがままでごめんなさい。。。

補足日時:2005/08/09 15:35
    • good
    • 0

フォームから変数を受け取るには、デコード処理が必要です。


デコード処理のサブルーチンを追加しました。→decode
はじめに表示する部分をサブルーチン化しました。→page

(1)デコード処理をします。
(2)IF文で変数の中身によって表示するページを判定します。


#!/usr/bin/perl

$script="test.cgi"

&decode;

if($in{'page1'}=="page1"){
&page1;
}else{
&page;
}
------------------------------------------------
sub page{
print <<"EOF";
Content-type: text/html

<html>
<head>
<meta content="text/html; charset=shift_jis">
<title></title>
</head>
<body>

あなたの注文したものは●●です。
よろしかったら次のページへを押してください。

<form method="post" action="$script">
<input type="submit" value="次のページへ">
<input type="hidden" name="page1" value="page1">
</form>

</body>
</html>
EOF
}
------------------------------------------------
sub page1{

print <<"EOF";
Content-type: text/html

<html>
<head>
<meta content="text/html; charset=shift_jis">
<title></title>
</head>
<body>
お買い上げありがとうございました。
</body>
</html>
EOF
}
------------------------------------------------
sub decode {
local($key, $val, $buf);

if ($ENV{'REQUEST_METHOD'} eq "POST") {
$postflag=1;
read(STDIN, $buf, $ENV{'CONTENT_LENGTH'});
} else {
$postflag=0;
$buf = $ENV{'QUERY_STRING'};
}

$flag=0;
@key=();
%in=();
foreach (split(/&/, $buf)) {
($key, $val) = split(/=/);
$key =~ tr/+/ /;
$key =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$val =~ tr/+/ /;
$val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$key =~ s/^\_//;
$in{$key} .= "\0" if (defined($in{$key}));
$in{$key} .= $val;
push(@key,$key);
}
}

この回答への補足

さっそくのお返事ありがとうございます。

教えてくださったものをこぴペしてみたのですが、
エラーがでてしまいました・・・

どこでエラーをはいてるのかちょっとわたしにはわかりません。。

補足日時:2005/08/09 15:15
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!