「みんな教えて! 選手権!!」開催のお知らせ

PerlのReadPerseについて質問させてください。
以下少々長いですが、過程を書きます。


<form>タグにより、入力フォームのページをHTMLで作成したとします(form.html)。
その際、<form method="post" action="form.cgi">
と入力しておいて、別途form.cgiを作成するとします。

form.htmlには、<form>タグ内のname属性で、それぞれ'weight' 'height' 'age'という三種類のデータを入力してもらって、取得するようにしています。

そして<input type="submit" value="登録">による、
登録ボタンを押すことで、
form.cgiに処理をさせるようにしています。


form.cgiの中身ですが、まず、最初の三行を書きます。

#!/usr/local/bin/perl
require 'cgi-lib.pl';
&ReadParse(*form);

となるのですが、わからないのが、
三行目の

&ReadParse(*form);

です。
サブルーチンReadParseを引数*formで、
cgi-lib.plから呼び出しているということはわかるのですが、いきなり*formという形で、ハッシュを登場させているあたりがわかりません。(この際、ハッシュ名の前の%を*に変えなければならないことは、一応知っております。理由はわかりませんが。)

そこで質問なのですが、
いきなり、ハッシュであるformを登場させていいものなのでしょうか??

以下、form.cgiの内容です。


#!/usr/local/bin/perl

require 'cgi-lib.pl';
&ReadParse(*form);

$name=$form{'weight'};
$sex=$form{'height'};
$megane=$form{'age'};

print "Content-type: text/html\n\n";
print "<html>\n";
print "<body>\n";

print "体重:${weight}<br>\n";
print "身長:${height}<br>\n";
print "年齢:${age}<br>\n";

print "</body>";
print "</html>";

_END_

A 回答 (15件中1~10件)

まずは動いてよかったですね。



というか、ケアレスミス・・・
私の書いたソースでは%formではなくて、%inにデータが代入されます。

> $in{$key} = $value;

ここです。ここを、

> $form{$key} = $value;

にすれば%formになりますが。

以前にも申し上げましたが私はAN HTTPDはよくわかりません。
私は基本的にFreeBSDとApacheな人なので・・・
このサービスは便利ですが、ちゃんと勉強したいと思ったらメーリングリストへの参加をお勧めします。
多少厳しい世界なので、あまりの「教えて君」は叱られますけどね。

コピペは・・・コピー元によるのではないでしょうか。
テキストファイルから普通にコピーするのは特に問題ないと思いますが、
ブラウザ上からのコピーなどはあまり思わしくないかもしれないです。

これからいろいろと勉強してみてください。
PerlだけじゃなくPHPやDBなど面白い事はいろいろありますよ。
頑張ってくださいね。
    • good
    • 0
この回答へのお礼

本当に最後までお付き合いしていただき、
ありがとうございました。

Perlは本当に面白いと思います。
たしかに厳しい世界ですが、コーディングの面白みにすっかりはまってしまいました。

これからどんどん作っていこうと思います。

メーリングリストですね。
わかりました。参加することにします。

ApacheもAN HTTPDもまだまだ使いこなせていませんが、もっと勉強いたします。

とにかくひたすら頑張るだけです。

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

お礼日時:2003/04/22 01:20

ログの内容からはPOSTが実行されている(言葉がなんか変です。

)ではなくて、
POSTにより/form.cgiをリクエストされて正常な結果を返している事しかわかりません。
POSTでデータが送出されてるかまではわからないんです。
ですが、CGIが正常に実行されている事はわかりました。

<form method="GET" action="form.cgi">

で、再度試してみてもらえませんか?
GETの場合、データをQUERY_STRINGに付けるのでログで確認が可能です。
また、ブラウザ上のアドレスバーにも
form.cgi?key=value...
という表示がされると思います。
    • good
    • 0
この回答へのお礼

お礼が遅くなりまして申し訳ございません。
何度も本当にありがとうございます。

本日も奮闘した結果、なんと表示されました!!

その詳細を報告いたします。

まず、結果としては、
お教えいただいていた、
if ( $ENV{'REQUEST_METHOD'} eq 'POST' ) {
read(STDIN,$buf,$ENV{'CONTENT_LENGTH'});
} else {
$buf = $ENV{'QUERY_STRING'};
}
foreach ( split(/&/,$buf) ) {
tr/+/ /;
($key,$value) = split(/=/);
$value =~ s/%(..)/pack('c',hex($1))/eg;
$in{$key} = $value;
}
を一度、元の

require 'cgi-lib.pl';
&ReadParse(*form);

に戻してみたところ、すんなりと表示されてしまったんです。

ひょっとしたら私が教えていただいていたスクリプトコードの置き方を誤っていたのかもしれません。

ですが、どうも腑に落ちないのは、
元々は、

require 'cgi-lib.pl';
&ReadParse(*form);

と記述していたということです。
それで動かなかったから、ikspiariさんの教えてくださったコードに置き換えたわけであり、
それをさらに元に戻して動くとなると、原因はやはりAN HTTPDにあって、そのあと私が置き換えたコードをミス表記していたということなのかなと思っています。
そのままペーストするのはまずかったのでしょうか?

明確な原因はよくわかりませんが、
気長におつきあいしてくださったおかげでひとまず正しくCGIが動作しているという
ことが目の前で確認ができたということにホッとしております。

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

お礼日時:2003/04/22 00:46

ログというのはHTTPDのログの事です。


Apacheでしたらaccess_logとerror_logというのがあり、
何時、何処から、何のファイルにアクセスされ、どういうステータスを返しているかが
リクエストされる都度に記録されていきます。
HTTPDやCGIの挙動がおかしい時にログをチェックするのはごく基本的な事です。

余談ですが、
通常、HTTPDのログは毎日更新して集計作業をします。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
遅くなりまして申し訳ございません。

ログについて全くの無知でした。
アドバイスありがとうございました。

HTTPDとApacheのログをじっくりと眺めていました。
すると、わかったのは、
log内には、たしかに、

127.0.0.1 - - [20/Apr/2003:00:48:35 +0900] "POST /form.cgi HTTP/1.1" 200 200

というようにpostが実行された様子を示しています。
となると、htmlが受け取れていない?
のでしょうか。

とにかくもうちょっとがんばります!

お礼日時:2003/04/21 00:35

どうしようもないことなんてないです。


人間と違って2進数で動いてる機械はとても素直です。

ブラウザから
http://127.0.0.1/form.cgi?weight=100
と指定したらform.cgiは正常に動きますか?
form.htmlからCGIを起動した時のログも確かめてください。
200のステータスが返ってますか?
    • good
    • 0
この回答へのお礼

ありがとうございます。

>どうしようもないことなんてないです。
人間と違って2進数で動いてる機械はとても素直です。

ごもっともだと思います。ここまできて投げ出すというわけにはいきません。こうなったら意地でも問題を解決します。

form.htmlからCGIを起動した時のログを確認しろとのことですが、ログというのは、このhtmlとcgiのコードの場合、存在しないと思うのですが、
どうなのでしょうか。

ひょっとしてログが鍵なんでしょうか??

お礼日時:2003/04/20 15:54

form.htmlから呼び出した時って、ほんとうにCGI実行されてるんですか?


ログ見てみましたか?
単純にform.htmlからCGIが起動してないだけのような気がするのですが・・・

<form action="http://127.0.0.1/form.cgi">

という感じでURLで指定してもダメでしょうか?
    • good
    • 0
この回答へのお礼

こんにちは。

やはり駄目でした。
こればかりはもうどうしようもないかと思っています。

とりあえず、しばらくいろいろと試行錯誤して、
また詳細をご連絡いたします。

いろいろと本当にありがとうございました。

お礼日時:2003/04/20 14:16

ごめんなさい、昨日あの後寝てしまいました。


常に説明が不足してまして申し訳ございません。

環境変数(%ENV)というのはその名の通りサーバの情報(環境)を持つ変数です。
例えば、
http://127.0.0.1/env.cgi?key=value
を実行した時に出力結果として
QUERY_STRING=key=value
と出れば正常です。
GETで送出した場合CGIは環境変数QUERY_STRINGからデータを読み込みます。
その前に書いたソースでそれは分かると思います。

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

上記処理は環境変数REQUEST_METHODがPOST*じゃない*と$bufに環境変数QUERY_STRINGを代入しています。
つまり通常はGETだった場合という解釈です。
?はセパレータなので省略されます。

私はAN HTTPDはわからないのですが、
挙動がおかしいようなので、アンインストールして最新バージョンをインストールするとか、
この際Apacheに変えるとかしてみてはどうでしょうか?
CGIを動かしてるのはHTTPDですから・・・
もう一度だけ、
http://127.0.0.1/env.cgi?key=value
で、QUERY_STRINGに値が入ってるか確認してみてください。
    • good
    • 0
この回答へのお礼

ありがとうございます。
お礼が遅くなりまして申し訳ございません。

ご指示通りのことを実行してみたところ、
QUERY_STRING=key=value
と正常に表示されました。

その後、いろいろ試してみた結果を申しますと、
CGIファイルでも簡易掲示板で、自身のファイルから、自身のファイルへの書き込みは問題なくできるようです。

つまりformのactionで、自分自身のcgiファイルを指定するという場合は、正常に実行されます。

今回のケースでは、form.htmlがform.cgiを呼び出すという命令でしたが、この場合は、ローカル環境では、an httpdでは不可能でした。
そこで、Apacheも導入して検証してみた結果、同様に実行は不可能になりました。
Apacheまで実行が不可能というのは、本当に意味がわかりませんが、
ActivePerlのバージョンがまずいという可能性はあったりするのでしょうか?

http://www.activestate.com/Products/Download/Dow …

上記ページの一番上の
MSIというのをDLして、インストールしています。
でも、他のファイルが実行できているので、
特にActivePerlに問題があるというのも考えにくいかなと思っています。

長い間お付き合いしていただきまして
本当にありがとうございました。

また何かわかれば補足に書き足させていただきます。

締め切りはもうしばらくお待ちください。

お礼日時:2003/04/19 19:06

説明下手ですみません。


ん~、ローカルなのでブラウザ立ち上げて、

http://127.0.0.1/form.cgi?key=value...

ですかね?
127.0.0.1
というのは「ループバックアドレス」と言ってlocalhostのIPアドレスです。
ソースの挿入位置は下の回答を参考にしてください。

すみませんが、頑張ってみてください。
    • good
    • 0
この回答へのお礼

ありがとうございます。

結果をご報告します。

まず、
http://127.0.0.1/form.cgi?key=value...
の結果ですが、form.cgiの画面が表示されましたが、値はやはり何も表示されていないままでした。

次に、
env.cgiの結果ですが、
以下のような長い文字列がブラウザに表示されました。一部、私の実名が出てしまうので****にしています。


QUERY_STRING=
APPDATA=C:\Documents and Settings\************\Application Data
CONTENT_TYPE=
HTTP_ACCEPT_LANGUAGE=ja
ALLUSERSPROFILE=C:\Documents and Settings\All Users
HTTP_CONNECTION=Keep-Alive
COMSPEC=C:\WINDOWS\system32\cmd.exe
REMOTE_PORT=1237
PATH_TRANSLATED=
HTTP_ACCEPT=image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, application/x-gsarcade-launch, */*
REMOTE_HOST=127.0.0.1
GATEWAY_INTERFACE=CGI/1.1
PATH_INFO=
REMOTE_ADDR=127.0.0.1
SCRIPT_NAME=/env.cgi
HTTP_ACCEPT_ENCODING=gzip, deflate
DOCUMENT_ROOT=C:\www\home
HOMEPATH=\Documents and Settings\*********
HOMEDRIVE=C:
HTTP_COOKIE=bbs_j73_read=sort_0; bbs_j73=delkey_123:url_http%3a//:mail_」・・ィ」・・ィ」・・name_」・凜・・凜
SCRIPT_FILENAME=C:\www\home\env.cgi
CONTENT_LENGTH=0
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS
COMPUTERNAME=***********
COMMONPROGRAMFILES=C:\Program Files\Common Files
CLIENTNAME=Console

私のPCのローカルサーバーの情報が書き出されているようです。一部文字化けしていたりします。
うーん、どうでしょう・・・?

また、たまにAN HTTPDを使用していて、cgiファイルを指定すると、cgiのソースがブラウザに表示されたりすることがあります。そうかと思えば、何事もなかったように、通常の表示に戻ったりします。やはりAN HTTPDの異常な気もします。

お礼日時:2003/04/18 21:30

更に補足です。


環境変数って出力されますか?

#!/usr/local/bin/perl

print "Content-Type: text/html\n\n";
while ( ($key,$val) = each(%ENV) ) {
print "$key=$val<BR>\n";
}
exit();

上記ソースをenv.cgiかなんかで保存して何か出力されるか試してみてください。
後、先ほどのソースは、

require 'cgi-lib.pl';
&ReadParse(*form);

の部分と置き換えてください。
    • good
    • 0

自分でソース書いた方が早いかもしれませんね。


以下のソースでcgi-lib.plと*基本的*には同じ働きをします。
%inに格納しています。

if ( $ENV{'REQUEST_METHOD'} eq 'POST' ) {
read(STDIN,$buf,$ENV{'CONTENT_LENGTH'});
} else {
$buf = $ENV{'QUERY_STRING'};
}
foreach ( split(/&/,$buf) ) {
tr/+/ /;
($key,$value) = split(/=/);
$value =~ s/%(..)/pack('c',hex($1))/eg;
$in{$key} = $value;
}

これで動かないようでしたら、HTTPDに問題があるかと思われます。
後はブラウザからアドレスを直接入力してGETで動作確認してみてください。
~/form.cgi?key=value...
って、感じで。
    • good
    • 0
この回答へのお礼

ありがとうございます。
ちょっと混乱してしまっているのですが、

if ( $ENV{'REQUEST_METHOD'} eq 'POST' ) {
read(STDIN,$buf,$ENV{'CONTENT_LENGTH'});
} else {
$buf = $ENV{'QUERY_STRING'};
}
foreach ( split(/&/,$buf) ) {
tr/+/ /;
($key,$value) = split(/=/);
$value =~ s/%(..)/pack('c',hex($1))/eg;
$in{$key} = $value;
}

というソースコードをどこに入れればいいのでしょうか?

アドレスから直接入力というのは、何のアドレスでしょう?

お手数お掛けします。

お礼日時:2003/04/18 20:33

すみません、お返事が遅くなりました。


「ローカルで実行されない。」という意味がそもそもわからないのですが。
それはHTTPDが500のコードを返すという事でしょうか?
全てのファイルを同一のディレクトリに入れているとの事ですが、
form.htmlのCGIへのパスはあってますか?

Apacheは英語ですが、そんなに難しくないですよ。
是非、挑戦してみてください。
OSもLinuxとかFreeBSDを入れると幸せになれます。;-)
# この言い回し少し古いかも...。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

ローカルで実行されないというのは、
つまり、form.cgi自体は表示されるのですが、
その値だけが表示してくれないという状態です。
form.html上のname属性で入力した値が、form.cgiでは実行されないということです。

どうやら連想配列に値が格納されていない?ようです。
undef値を返している?のでしょうか。

ところが、不思議なことに、リモートのサーバー上で実行すると、なぜかform.cgiにきちんと値が表示されるのです。

しばらく奮闘してみます!

Apache難しくないんですね。
うーん、英語にびびっていてはしょうがないですよね。でも、AnHTTPDと競合しないのかなぁと少し心配だったりします。
既にローカルが異常?なようなので、この際、毒を食らわば皿までということで、挑戦してみますね。

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

お礼日時:2003/04/18 20:10

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

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報