• ベストアンサー

(Perl)ReadParseによるハッシュへの格納について

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_

  • shevy
  • お礼率67% (703/1046)
  • CGI
  • 回答数15
  • ありがとう数25

質問者が選んだベストアンサー

  • ベストアンサー
  • ikspiari
  • ベストアンサー率48% (29/60)
回答No.15

まずは動いてよかったですね。 というか、ケアレスミス・・・ 私の書いたソースでは%formではなくて、%inにデータが代入されます。 > $in{$key} = $value; ここです。ここを、 > $form{$key} = $value; にすれば%formになりますが。 以前にも申し上げましたが私はAN HTTPDはよくわかりません。 私は基本的にFreeBSDとApacheな人なので・・・ このサービスは便利ですが、ちゃんと勉強したいと思ったらメーリングリストへの参加をお勧めします。 多少厳しい世界なので、あまりの「教えて君」は叱られますけどね。 コピペは・・・コピー元によるのではないでしょうか。 テキストファイルから普通にコピーするのは特に問題ないと思いますが、 ブラウザ上からのコピーなどはあまり思わしくないかもしれないです。 これからいろいろと勉強してみてください。 PerlだけじゃなくPHPやDBなど面白い事はいろいろありますよ。 頑張ってくださいね。

shevy
質問者

お礼

本当に最後までお付き合いしていただき、 ありがとうございました。 Perlは本当に面白いと思います。 たしかに厳しい世界ですが、コーディングの面白みにすっかりはまってしまいました。 これからどんどん作っていこうと思います。 メーリングリストですね。 わかりました。参加することにします。 ApacheもAN HTTPDもまだまだ使いこなせていませんが、もっと勉強いたします。 とにかくひたすら頑張るだけです。 本当にありがとうございました。

その他の回答 (14)

noname#48234
noname#48234
回答No.4

三度、登場です(笑)。 そうなると、やはりローカル環境が怪しいですね。 ローカル環境でテストするのは今回が初めてでしょうか? 他のスクリプトでは正常に動作していましたか? <思い当たるチェック箇所> (1)まさかとは思いますが、Perlはインストールされていますよね? (2)CGIスクリプトの1行目のPerlへのパスが実際のローカル環境と一致していますか? (3)スクリプトの最終行の_END_を削除してみてください。 とりあえず、この3点を・・・。 なんとか動いてほしいですね。

shevy
質問者

お礼

ご回答ありがとうございます。 本当にお付き合いありがとうございます。 非常に頼もしい限りですm(_ _)m ローカル環境でのスクリプトの実行は今までずっと正常に動いていました。 datファイルの読み込みもアクセスカウンタ作成時にうまく動作していました。 perlのインストールは、activeperlをインストールしています。xpですのでDOSプロンプトで、perl -vと入力して、念のため再度確認しましたがばっちりインストールされております。 早速、massasoytさんがおっしゃられるチェック箇所を チェックしてローカルで確認してみました。 (1)上記に記述しましたようにperlはインストールされています。 (2)ANHTTPDのperlへのパスと同一です。 つまり、今までテストしてきたほかのスクリプトの一行目と同一です。 (3)ENDを削除してみましたが、やはり駄目でした。ENDというのは、そもそも必要ないものなんでしょうか? 私のローカル環境はどうなっているのでしょう。。 この際、Apacheに乗り換えようかと思います。 ただ英語なので敷居が高いかなと少し心配ですが。 不思議なのは、他のカウンターなどのcgiは問題なく動いてくれることなんです。はああ・・・。 massasoytさんにもう一点だけお尋ねしたいのですが、 form.cgiにおける、 &ReadParse( *form ); という部分の*formは、別に*sunというような、 別の名前でもきちんとform.htmlからname属性の値を受け取ることができるのでしょうか? <form>タグで作成されたデータは、 必ず*formという名称で、ハッシュに格納しなければならないのでしょうか? その部分だけかなり気になっていますので、どうかご教授ください。 宜しくお願いします。

noname#48234
noname#48234
回答No.3

#2、修正です。 #2<正>の後半 print "年齢:form{'age'}<br>\n"; ↓ print "年齢:$form{'age'}<br>\n"; $マークが抜けてました。

shevy
質問者

お礼

たびたび失礼します。 ローカル環境のチェックしていなかったのですが、 リモートのサーバーにアップして実行してみると、 なんとうまく値がform.cgiに表示されてしまいました。 となると、スクリプト自体は先ほど私がmassasoytさんにご確認をお願いした内容で正常のようです。 となると、なぜ、ローカルにおいてはform.cgiが実行されないのか、本当にわからなくなってしまいました。 私の環境で怪しい部分というのはあるでしょうか。 ローカルサーバー:ANHTTPD ローカルにおいてはcgiファイルもhtmlファイルもすべて同一ディレクトリで実行。 リモートにアップする際は、cgi-binフォルダにcgiファイルをアップする必要があったので、パスだけはリモート用に変更しました。

shevy
質問者

補足

>ローカル環境のチェックしていなかったのですが ↓ ローカル環境のチェックしか、していなかったのですが の間違いです。紛らわしい書き方にしてしまいまして、済みません。

noname#48234
noname#48234
回答No.2

こんにちは。 &ReadParseの用法、意味については#1さんの仰っている通りですね。 では、私はスクリプトの修正を。 form.cgiの以下の部分に問題ありです。 <誤> print "体重:${weight}<br>\n"; print "身長:${height}<br>\n"; print "年齢:${age}<br>\n"; <正> print "体重:$name<br>\n"; print "身長:$sex<br>\n"; print "年齢:$megane<br>\n"; もしくは print "体重:$form{'weight'}<br>\n"; print "身長:$form{'height'}<br>\n"; print "年齢:form{'age'}<br>\n"; です。 <アドバイス> (1)以下の部分の意味はお分かりですか? $name=$form{'weight'}; $sex=$form{'height'}; $megane=$form{'age'}; 後々%formの内容を呼び出したり使いまわす際に、いちいち$form{'***'}と書かなくて済むように簡単な変数に代入しています。shevyさんのスクリプトでは折角簡単な変数に代入したのに、HTML表示の際に使っていませんね。簡単な変数$name,$sex,$ageを使わなくても呼び出せますが、shevyさんのスクリプトではその呼び出し方法も間違っています。簡単な変数を使う場合は<正>の前者、ReadParseで自動的に作られた%formから直接呼び出すのであれば<正>の後者です。 (2)このスクリプトは参考書か何かを見ながら例文を流用してお書きになったのでしょうか? $name=$form{'weight'}; $sex=$form{'height'}; $megane=$form{'age'}; 変数名と実際の数値の内容がバラバラですね。 $nameが体重、$sexが身長、$meganeが年齢。簡単な短いスクリプトや自分しか編集しないスクリプトならOKですが、複雑で長いスクリプトや他人が編集する可能性がある場合は混乱を避けるため変数名と中身を合わせた方が良いです。 例えば、 $weight=$form{'weight'}; $height=$form{'height'}; $age=$form{'age'}; 変数名はあくまでも任意ですが・・・。 (3)from.cgi内のcgi-lib.plのパスは合ってますよね? 一応、上記修正後テストしたら表示されました。

shevy
質問者

お礼

非常にご丁寧にありがとうございました。 変数名、間違えておりました。ご指摘ありがとうございます。massasoytさんのご指摘どおりで、このスクリプトは某書籍の内容を自分でいじくったものです。 そこで、早速訂正してみました。 簡単な変数に代入するという方法で行いました。 ですが、やはりform.cgiには反映されないようです。 以下、長くなりますが、スクリプトを載せます。 お手数お掛けしますが、massasoytさんの環境でform.cgiにきちんと値が表示されるかどうかをご確認お願いできますでしょうか。 サーバーはANHTTPDを使用しています。これまでは何の問題もなくcgiのテストができていました。 form.cgi内のcgi-lib.plのパスはform.cgiと、cgi-lib.plが同一ディレクトリに置いておりますので下記スクリプトの書き方で正しいと思われます。 form.cgiのスクリプト --------------------------- #!/usr/local/bin/perl require 'cgi-lib.pl'; &ReadParse(*form); $weight=$form{'weight'}; $height=$form{'height'}; $age=$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_ ここで一杯になりましたので、補足に、 form.htmlのコードを書きます。 お手数お掛けします。

shevy
質問者

補足

form.htmlのスクリプト --------------------------------------- <html> <body> <form method="post" action="form.cgi"> 体重:<input type="text" name="weight"> <p> 身長:<input type="text" name="height"> <p> 年齢:<input type="text" name="age"> <p> <input type="submit" value="登録"> <input type="reset" value="クリア"> </form> </body> </html> ------------------------------------ もしこれでmassasoytさんの環境で実行されたとしますと、 私のローカルサーバーに何か問題があるのでしょうか? お手数お掛けいたしますが、お返事をお待ちしております。宜しくお願いします。

  • ikspiari
  • ベストアンサー率48% (29/60)
回答No.1

cgi-lib.plはPOSTまたはGETで送信した値を連想配列に格納するPerlライブラリです。 通常CGIにデータを渡す時の形式が、 key=value&key2=value2&key3=value3... という感じで、キーと値を=で繋ぎ、 その組み合わせが複数ある場合&で繋がれてCGIに送出されます。 単純な説明ですが、cgi-lib.plは最初に&で区切り、 次に=で区切ったキーと値を連想配列に格納します。 ちなみに、&ReadParse();で引数を渡さないと%inに格納されます。 CGIに渡されcgi-lib.plで連想配列化されたデータをどう使おうと構いません。

shevy
質問者

お礼

早速のご回答ありがとうございます。 少し難しくて、今頭を悩ませています。 実はform.htmlで入力した内容が、 form.cgiに反映されなくなってしまいました。 以下のhtml文書で、form.cgiが働いてくれるはずなんですが、form.cgiにはname属性が受け渡しされていない?ようです。間違いをご指摘してくださらないでしょうか。 <html> <body> <form method="post" action="form.cgi"> 体重:<input type="text" name="weight"> <p> 身長:<input type="text" name="height"> <p> 年齢:<input type="text" name="age"> <p> <input type="submit" value="登録"> <input type="reset" value="クリア"> </form> </body> </html>

関連するQ&A

  • perlがうごきません

    htmlファイルには <html> <form action="form2.cgi" method="get"> 食品名1<input type="text"name="form1"> <br> 食品名2<input type="text"name="form2"> <input type="submit"value="送信"> </form> </html> cgiファイルには #! /usr/bin/perl require "cgi-lib.pl"; &ReadParse(); print "Content-type:text/html\n"; print "\n"; print "<html>\n"; print "<head>\n"; print "<title>フォーム</title>\n"; print "</head>\n"; print "<body>\n"; print "おいしい$in{'form1'}\n"; print "まずい$in{'form2'}\n"; print "</body>\n"; print "</html>\n"; exit; cgi-lib.plはサーバーにいれております。 どうしてうごかないのでしょうか。 perlの場所も正確です。

    • ベストアンサー
    • Perl
  • jcode.pl と &ReadParse()

    CGIファイルの先頭は #!/usr/local/bin/perl require './cgi-lib.pl'; require './jcode.pl'; &ReadParse(); という感じになっています。 ここでのの require は、日本語を使うためのもの だと思っています。合っていますか? &ReadParse() というのは何ですか? require と関係があるみたいです。 require を書かずに &ReadParse() を書くとCGIエラーになります。

    • ベストアンサー
    • CGI
  • Perlがサーバー上でうごきません

    htmlファイルには <html> <form action="form2.cgi" method="get"> 食品名1<input type="text"name="form1"> <br> 食品名2<input type="text"name="form2"> <input type="submit"value="送信"> </form> </html> cgiファイルには #! /usr/bin/perl require "cgi-lib.pl"; &ReadParse(); print "Content-type:text/html\n"; print "\n"; print "<html>\n"; print "<head>\n"; print "<title>フォーム</title>\n"; print "</head>\n"; print "<body>\n"; print "おいしい$in{'form1'}\n; print "まずい$in{'form2'}\n; print "</body>\n"; print "</html>\n"; exit; cgi-lib.plはサーバーにいれております。 どうしてうごかないのでしょうか。

    • ベストアンサー
    • Perl
  • cgi-lib.plのReadParse関数

    あるパールからcgi-libを呼び出して、ReadParse関数を使おうとするとInternal Server Errorがでてしまいます。 パールの中身は #!/usr/local/bin/perl require 'cgi-lib.pl'; require 'jcode.pl'; &ReadParse(*in); です。 そこで3行目と5行目の行頭に#をつけて飛ばすとパールは正常に動きます。 これってcgi-lib.plのReadParse関数がいけないんでしょうか? ダウンロードしたまま何も変更していないのに..... ちなみにサーバーのパールのバージョンは5.004のようです。

    • ベストアンサー
    • CGI
  • Perlのファイルのアップロードの方法についてお聞きします。

    Perlのファイルのアップロードの方法についてお聞きします。 &ReadParseを用いた方法で、 $file = $in{'TENSOU'};で$file自体にデータが入るので 簡単だなと思っていましたが、送信元と送信後のファイルが若干違っていました。 使い方が間違っているのでしょうか? 以下、サンプル ◆HTML側 <FORM ACTION="up.cgi" ENCTYPE="multipart/form-data" METHOD="POST"><P> ファイル: <INPUT TYPE="file" NAME="TENSOU" SIZE="32"><BR> <INPUT TYPE="submit" VALUE="送信"> </FORM> ◆Perl側 &ReadParseの例を用いた方法 #!/perl/bin/perl #!/usr/local/bin/perl use CGI; use CGI::Carp qw(fatalsToBrowser); #--->エラー対策 require 'cgi-lib.pl'; require 'jcode.pl'; $BUFSIZE = 2048; &ReadParse; # ==> 強力な変換 $file = $in{'TENSOU'}; # ==> 実態自体がデータなので、取り扱いしやすい $file_size = length($file); $file_size *= ($BUFSIZE / 1024); open(OUT, "> test.jpg"); print(OUT $file); close(OUT); print "Content-type: text/html\n\n"; print "$file_size(KB)<br>\n"; print "<a href=\"test.jpg\">テスト</a>\n"; exit;

    • ベストアンサー
    • CGI
  • なぜエラー?

    フォームに書き込まれた内容をCGIへ送る練習をしているのですが、どーーーーしてもエラーがでます(泣) 何故でしょうか。(改行や日本語処理はおいておいて下さい) CGI側をコピペしてみます。 #!/usr/local/bin/perl require 'lib/cgi-lib.pl'; &ReadParse(*form); print "Content-type: text/html\n\n"; print "<html>\n"; print "<head><title></title></head>\n"; print "$form{'kousin'}\n"; print "</body>\n"; print "</html>\n"; __END__ でエラー内容が # lib/cgi-lib.pl did not return a true value. File 'Macintosh HD:Desktop Folder:home:new:new.cgi'; Line 3 です。 cgi-lib.plは置き場所を変更してみたりしてるんですが、どこに置いても同じです。Line3ってこれ以上どーすればいいのでしょう‥‥うぅ。 MacOSでMacJPerl、サーバーにQuid Pro Quoを使ってます。

    • ベストアンサー
    • Perl
  • Perlをcshスクリプトに書きなおしたい

    以下のPerlで書かれたCGIをcshスクリプトに書き直したく思っています。 #!/usr/local/bin/perl # load libraries require ("/usr/local/bin/cgi-lib.pl"); # cancel stdout buffering $| = 1; # header response print "Content-type: text/html\n\n"; print STDOUT "<HTML><HEAD></HEAD><BODY>\n"; &ReadParse; open(COMM, "|./message > ./message.out") || die; $in_text = $in{"Name"}; print COMM "Name: $in_text\n"; ... "Name"という変数名で受け取った文字列を$in_textに代入している ようですが、この辺りの処理、cshではどう書けばよいのでしょうか。

    • ベストアンサー
    • CGI
  • 日本語文字化け(GETメソッド?)

    以下のようにすると日本語の受け渡しがうまくいきません。(抜粋) そももこの場合、日本語の受け渡しは、出来ないのでしょうか。 それともコンバートのやり方がまずいのでしょうか。 お知恵をおかしください。宜しくお願い致します。 URL:test.cgi?name=日本語 #!/usr/local/bin/perl require './cgi-lib.pl'; require './jcode.pl'; # 読込 &getinput; $name = $form{'name'}; print "Content-Type: text/html\n\n", $name; exit; sub getinput { &ReadParse; while (($key,$val) = each %in) { &jcode'convert(*val, "sjis", "", "z"); $form{$key} = $val; } }

    • 締切済み
    • CGI
  • perlで受取ったパラメータをバイトコードのまま変数に代入

    HTMLフォームの、name=aのテキストボックスに「あ」と入力しCGIにSubmitすると、a=%82%A0とバイトコードに変換されわたされますよね 受け側のCGIで下記の様にそのパラメータを$aに代入すると、$aには「あ」となって代入されるのですが、あえて「あ」ではなくバイトコードの「%82%A0」で代入するようにするには、どうしたらよいのでしょうか? #!/usr/local/bin/perl require 'cgi-lib.pl'; require 'jcode.pl'; &ReadParse; $a=$in{'a'};

    • ベストアンサー
    • Perl
  • IIS の@INC ERRORについて教えて

    wiin8にIISとPerl64をインストールしました。「Default Web Site」を「C:\wabs」に設定。 tst.cgi #!/usr/local/bin/perl print "Content-Type: text/html", "\n\n"; print "<HTML>\n"; print "<BODY>\n"; print "こんにちは!<BR>\n"; print "</BODY>\n"; print "</HTML>\n"; で、無事に動いてると確認したのですが、 C:\wabs\lib\jcode.pl を設置して、 require './lib/jcode.pl'; として、実行すると ERROR = Can't locate ./lib/jcode.pl in @INC (@INC・・・・ と、 パスが通っていないようなメッセージが出て、解決策が解らず困っています。 どなたか、解決策を教えてください。よろしくお願いします。

専門家に質問してみよう