PageID:Perl CGI Sample & Link
Last updete:97.03.17

Perlによる簡単なCGIプログラムのサンプル/リンク集

Perlによる簡単なCGIプログラムのサンプルとリストです。

自宅やスタンドアロンでテスト環境を作ってみたい方は下記を参照ください。
Macユーザの方
MacPerl関連情報: MacでPerlのページ
WebStar・MacHTTP等WWWサーバ(httpd)の情報: MacでWWW & Perlのページ

Windowsユーザの方
WindowsNT/95でWWW & Perlのページ
WindowsNT/95でPerl : Perl for Win32 (NTPerl)

当ページのメニュ−

●CGI処理に必携のモジュール
●フォームの入力をデコード:jcode.plを使用
●フォームの入力をデコード:nkfを使って一括処理する方法
●フォームに入力されたバイナリ(16進)の制御文字を処理したい時
●CGI_Lite-1_62.pmについて。CGI_Liteモジュールの解説/例を和訳。
●CGI-Lite.pmを使った例
●cgi-lib.plを使った例(日本語モード)
●CGI.pmを使った例1(英語モード):要Perl5
●CGI.pmを使った例2(英語モード):要Perl5
●LWP::UserAgentを使った例
●LWP (libwww)モジュールを利用した例
●CGI.pmもCGI-lib.plもない場合
◆Jim Owen氏による簡単なフォームとスクリプトサンプル(英語モード)
◆Peter Seibel氏によるサンプル(英語モード)

●参考URLリスト

Perlなんか勉強せずにCGIを使ったツールを利用したいという方には

http://worldwidemart.com/scripts/(英語)
http://www.rescue.ne.jp/[ネットサーフレスキュー (Web裏技)]

Perl CGI関連ページ

Link for CGI  (日本語)97.03.16追加
CGI関連ページへのリンク集です。金子 篤嗣さん作。
Making INTERACTIVE PAGE(How to make CGI and SSI) (日本語)
About NCSA httpd  (日本語)
all about the first Internet(日本語)
About CGI (日本語)
CGI の書き方、入力のデコード法の FAQ 集 (日本語)
tutorial (日本語)
WWW Security (日本語)
World Wide Web FAQ (日本語)
「インターネット入門講座」 96.03.17追加
語句の学習、HTMLなどの基礎から、WWWサーバ構築法、CGIなどの 応用までの学習ができます。武藤知子さんによる運営。

YAHOOに登録されているリンク(96.11.25現在)

#ヤフーさん、勝手に転載してご免なさい。
  • インターラクティブホーム・ページ - CGIを使ったホーム・ページの作り方を紹介。 Perlのサンプルプログラムや、サーバーの設定方法、カウンタの作り方なども掲載。
  • 特設ホームページ作成相談室 - HTMLの書き方、カウンタ、伝言板、チャットの作り方、CGI、SSI、Java、Perl等、ホーム・ページ作成のための情報交換ルーム。
  • Perlで遊ぼうML - 快適なperlライフを送りたい人のためのメーリング・リストの紹介。
  • Perlのタコ - CGIプログラムの解説とソース。
  • 勝手にPerlリファレンス - CGI作成に役立つPerlのリファレンス。「小技を集めた」TIPSもあり。

    その他のPerl CGI関連ページ(英語)

    ftp://ftp.cc.umr.edu/pub/cgi/cgiwrap
    CGI FAQ
    Perlにおける CGI Form 処理に関する情報
    The cgi-lib.pl Home Page
    "guestbook"を処理するための簡単なスクリプト: post/email


    目次

    ●CGI処理に必携のモジュール

    (1)CGI-Lite.pm Perl5初級者必携。 CGI_Lite-1.xx.pm.gz

    (2)cgi-lib.pl Perl4愛用者必携。 参考ページ: http://cgi-lib.berkeley.edu/" (3)CGI.pm Perl5の鉄人ご愛用。やや重装備ですが、CGIに必要な機能の多くをカバーしています。 参考ページ: ftp://ftp.kdd.lab.co.jp/lang/perl/CPAN/modules/by-category/15_World_Wide_Web_HTML_HTTP_CGI/CGI/CGI.pm-2.56.readme 入手先: http://www.perl.com/CPAN/modules/by-module/CGI
    目次

    ●フォームの入力をデコード:jcode.plを使用

    注)入力データが各項目毎に切れてしまうので、 漢字コードの自動判定を誤る可能性があります。

    #!/PERLPATH/perl -wT require 'jcode.pl' read(STDIN,$IN,$ENV{'CONTENT_LENGTH'}) @pairs = split('&', $in); foreach $pair (@pairs) { ($name, $value) = split('=' , $pair); $value =~ tr/+/ /; $value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C" , hex($1))/egi; #formからの2バイトコード等の非キャラクタコードは #%ffの形にエンコードされるため、デコード &jcode'convert(*value, 'sjis'); #SJISを使用する場合(通常EUCが無難)。 $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/egi; &jcode'convert(*name,'sjis'); $FORM{$name} = $value; # $FORM{フォームの入力フィールド名}で変数値を参照可能となる。 }
    目次

    ●フォームの入力をデコード:nkfを使って一括処理する方法

    From: m-kwbr@nisiq.net (Minoru Kuwabara) Newsgroups: fj.lang.perl Message-ID: <m-kwbr-0101960956580001@d13.pm1.nisiq.net> [改行位置等変更] # recieve, decode and convert $_ = <STDIN>; $_ =~ tr/+/ /; $_ =~ s/%([A-F0-9][A-F0-9])/pack("C", hex($1))/gie; $_ =~ s/'/'\\''/g; #\\'-->\'(正規表現)、\'-->'\''(echoでのunmachを防ぐため) open(NKF,"echo '$_' | $nkf -e |"); #'$_'($_の中の特殊コードをクォートするため) while (<NKF>) { $input .= $_; } close(NKFCVT); chop $input; # split @pairs = split(/&/, $input); foreach (@pairs) { ($name, $value) = split(/=/, $_); $FORM{$name} = $value; } nkfを使って一括してコード変換をしてしまおうとするものです。 catが終わらないとう最初の問いは、質問者の意図を超えて、思いがけず広がりを呼びました。 斎藤さんからのechoを使った回答と、echoでの特殊キャラクタのクォート問題が、 土井さんとの間で、議論されました。シングルクォーテションのクォート方法は、 田中さんのフォローで解決しました。この方法は、あまり一般的ではないか も知れませんが、nkfしか使えない場合では必要(質問者のケース)だし、入力データを一 括して扱うので、漢字コードの自動判定が誤る危険が少なくなると思います。  また、これに関しては、utasiroさんから、echoを使わずにやる方法も示されました。 (コメントを付けて2行を、以下の3行で置き換える。) open(NKF,"- |"); open(STDOUT,"| $NKF_E "); print( $input); # utashiroさんの示されたのは、 open(NKF,"- |")||(open(STDOUT,"| $NKF_E")&&print($input),exit);  それから、佐久間さんからは、perl5で提供される、Kconv.pmのことが紹介されました。
    目次

    ●フォームに入力されたバイナリ(16進)の制御文字を処理したい時

    Jim Owen氏によるサンプル(英語モード)。<jim@charlie.webserve.com> Newsgroups: comp.lang.perl.misc Message-ID: <Pine.LNX.3.91.951010121025.22907A-100000@charlie.webserve.com> # バイナリ(16進)の制御文字を英数字に変換 $KEY =~ s/%(..)/pack("c",hex($1))/ge; $VALUE =~ s/%(..)/pack("c",hex($1))/ge;
    目次

    ●cgi-lib.plを使った例(日本語モード)

    #!perl -wT $|=1; require 'cgi-lib.pl' require 'jcode.pl' &ReadParse(*in); print <<EOF; Content-type: text/html <HTML> <HEAD> <TITLE>hoge</TITLE> </HEAD> <BODY> EOF if ($in{'入力フィールド名'}){ $value = $in{'入力フィールド名'}; &jcode'convert(*value, 'euc'); print "$value"; } else { print "name_no_value"; } hogehoge等々 print "</BODY></HTML>";
    目次

    ●CGI.pmを使った例1(英語モード):要Perl5

    From: Tom Christiansen <tchrist@mox.perl.com> Newsgroups: comp.lang.perl.misc,comp.infosystems.www.authoring.cgi Message-ID: <47eeor$rcp@csnews.cs.colorado.edu> In comp.lang.perl.misc, ian@wordsimages.com (Ian Taylor) writes: :Does anyone know of any examples of scripts to process the output of a :<SELECT MULTIPLE></SELECT> list box in an HTML form. For example if a :user selects January, February, April from a list box and submits it, how :does one get all three values as opposed to just a single value. :HTMLフォーム上で <SELECT MULTIPLE></SELECT> リストボックスの出力を :処理するスクリプトの例を誰かご存じありませんか。例えば、利用者がリストボックス :からJanuary, February, Aprilを選択してsubmitした場合、単一値ではなく3つの値 :全てを得るにはどうすればよいのでしょうか。 Oh, this is very easy. Suppose you have something like this: えー、非常に簡単なことです。こんな物があると考えてみて下さい: <TITLE>Card Colors</TITLE> <FORM METHOD="POST" ACTION="cgi-bin/colors"> <SELECT NAME="Colors" MULTIPLE> <OPTION VALUE="white">White <OPTION VALUE="green">Green <OPTION VALUE="red">Red <OPTION VALUE="black">Black <OPTION VALUE="blue">Blue <OPTION VALUE="gold">Gold <OPTION VALUE="colorless">Colorless </SELECT> </FORM> If you wanted to have the same foo.cgi contain the initial html as which processes it, you might do this: 同じfoo.cgiで初期化htmlと同時に処理もさせたいと思うのなら 下記のようにしてみましょう。 #!/usr/bin/perl -wT require 5.001; #最新版5.003を使用するときは当然5.003 use strict; use CGI; $query = new CGI; print $query->header; print $query->start_html('Card Colors'); print $query->startform; print "Pick some colors: "; print $query->scrolling_list('colors', [ qw(White Green Blue Red Black Gold Colorless) ], ['Blue', 'White'], 5, 1 ); print $query->submit('submit','Run Me'); print $query->endform; if ($query->param) { print "<HR><H1>Results</H1>"; @got = $query->param('colors'); print "Colors Selected: @got\n"; } You could also import the colors into one of your namespaces, like Q::, which is standard: また、colorsを Q:: のような名前空間の一つにインポートする事も可能です。 それが標準なんです。 if ($query->param) { print "<HR><H1>Results</H1>"; $query->import_names('Q'); print "Colors Selected: @Q::colors\n"; } On the other hand, you might also prefer a separate page. Here's how to handle that page, using the full CGI::Request interface: 他方で、別なページが要るかもしれません。 ここでは、そのページを処理する方法を全CGI::Requestインターフェースを 使って示します。 #!/usr/bin/perl -w use CGI::Request; SendHeaders(); unless ($req = new CGI::Request) { print "<H1>Warning</H1>Please post a proper request."; exit; } @colors = $req->param('colors'); print "<HR>"; print "Colors Selected: @colors\n"; So in any event, what you need to do is get a new CGI or CGI::Request object, then call the param() method on the object for which widget name you want, or else just call import_names() to get everything imported into your name space. ですから、あらゆるイベントの中でスル必要があることは new CGI または CGI::Request をgetし、望んでいるウィジェット名用のオブジェクトの param()メソッドをcallするか、あるいは名前空間にインポートしたもの 全てをgetするため import_names() をcallすることなのです。 You'll find debugging much easier if you get my CGI/ErrorWrap.pm module and start your programs this way: CGI/ErrorWrap.pmがあって下記のようにプログラムを始めれば、 デバッギングがずっと簡単になることがわかるでしょう。 #!/usr/bin/perl -Tw use CGI::ErrorWrap; use CGI; あるいは #!/usr/bin/perl -Tw use CGI::ErrorWrap; use CGI::Request; 詳細は ftp://perl.com/perl/CGI/lib-perl5/ErrorWrap.pm を参照して下さい。
    目次

    ●CGI.pmを使った例2(英語モード):要Perl5

    From: peacock-m@titania.HSC.Colorado.edu (Michael Peacock) Newsgroups: comp.lang.perl.misc Message-ID: <48tf6r$dkk@tali.UCHSC.edu> In article <1745CDEECS86.CHADM1@UConnVM.UConn.Edu>, CHADM1@UConnVM.UConn.Edu says: > >Could some kind soul show me how (under WWW conditions) >from a Perl calling program to a Perl >called program, to pass parameters, using the CGI.pm library? >I tried: >called_prog.pl(arg=value); >to no avail. >THere is a tiny note about $query->param, but I can't fathom how to >create the arguments in the first place. >Thanks, especially if anyone has a simple example. >Could you reply directly, as reading these news groups through the >mainframe is very difficult. >Thanks. >Carl David どなたか(WWWで)CGI.pmライブラリを使って、プログラムをcallしたPerlから callされたPerlへパラメータを渡す方法を教えて頂けませんか。 called_prog.pl(arg=value); と言う風に試したのですが駄目でした。 $query->paramについてちょっとしたノートはありますが、最初の所に 引数を生成する方法がよく理解できません。 CGI.pm is designed to let you write cgi scripts that output html and handle GET or POST queries from forms. Here's a little ditty that calls itself; hope it's useful to you: CGI.pmはhtmlを出力しフォームからのGETあるいはPOSTでの問い合わせを 処理するcgiスクリプトを書くようデザインされています。 下記は自分自身をcallする短いコードです。;参考になればいいですが。 #!/usr/bin/perl # save this file as ~server-root/cgi-bin/redo.cgi # Init the Library, and print HTML header #~server-root/cgi-bin/redo.cgiとしてこれを保存して下さい。 #ライブラリを初期化しHTMLヘッダをprint use CGI; $query = new CGI; print $query->header; # If this is the first time calling this cgi, # then do the input form. Otherwise, process the form #初めてこのCGIをcallした場合、入力フォームを出します。 #それ以外はフォームを処理します。 # ==================================================== if ($query->param) # We have already made the query and we # want to output the search results            #既に問い合わせをしていてその結果を            #出力したい { # Get the values of the passed parameters #渡すパラメータの値を入手 # ======================================= $prop_type = $query->param('Properties'); $plan_type = $query->param('Plan'); $price = $query->param('Price'); $prop_type =~ tr/A-Z/a-z/; $plan_type =~ tr/A-Z/a-z/; # Present Query Results #問い合わせ結果を表示 # ===================== print $query->start_html("Database Search Results"); print <<"html";  #htmlマーカ(ここ)までを出力 <H1>Database Search Results</H1> <HR> <P>You have made the Following Selections</P> <HR> html  #ここ print "<h3>You have selected to search for $prop_type properties, costing less than $price"; print "<A HREF=/cgi-bin/redo.cgi>Do another search</A>"; print $query->end_html; } # IF $query->param # ここまでは$query->paramがあった場合 else { # This is our first time through      # ここは初回のみ通過 $method = "POST"; $action = "/cgi-bin/redo.cgi"; print $query->start_html("Search Our Database"); print <<"html"; <H1>Search the Database</H1> <P>Use this form to query our database of different properties</P> <HR> html print $query->startform($method,$action); print "<HR><P>Select the type of property you're interested in:"; print $query->popup_menu('Properties',['Business Office', 'Industrial', 'Residential']); print "<p>Do you wish to lease or purchase:"; print $query->checkbox_group('Plan',['Lease','Purchase']); print "<p>What is the maximum price you will consider?"; print $query->popup_menu('Price',['250000', '500000', '1000000', '1500000', '2000000','2500000']); print "<HR>"; print $query->submit('Submit Form'); print $query->reset; print $query->endform; print $query->end_html; }
    目次

    ●LWP::UserAgentを使った例

    From: merlyn@stonehenge.com (Randal L. Schwartz) Newsgroups: comp.lang.perl.misc,comp.infosystems.www.authoring.cgi Message-ID: <ukn3beszba.fsf@linda.teleport.com> [followups directed to the CGI group] >>>>> "eBORcOM" == eBORcOM <eborcom@eborcom.com> writes: eBORcOM> I want to write a Perl script which can simulate an HTTP post so I don' t eBORcOM> have to ue fill in forms from a web page but can do it direct from a Un ix eBORcOM> shell using Perl. eBORcOM> Does anyone have any advice or ideas as to how I should go about this o r has eBORcOM> such a thing already been done? Yeah, get LWP, from http://www.oslonett.no/home/aas/perl/www/. Here's a script that pretends it is filling in fields from the "What's On Tonight" TV listings search page http://www.tv1.com/wot/srcform2.htm, looking for everything on HBO and SHOWTIME today and tomorrow (using PST), looking for all entries that have descriptions that include /Stonehenge/, generating an HTML page in the process. Yes, it's dense, and there are a lot of tricks and tips in here. It's useful to view-source the original form and figure out what they are looking for. ================================================== snip #!/usr/bin/perl use lib "/home/merlyn/Lwp"; # this is where I keep it use LWP::UserAgent; $ua = new LWP::UserAgent; $headers = new HTTP::Headers; $headers->header('Content-type','application/x-www-form-urlencoded'); ## print "Content-type: text/html\n\n"; print "<html><head><title>Selected shows today and tomorrow</title></head>\n"; print "<body><h1>Selected shows today and tomorrow</h1>\n"; for $day (&day(0),&day(1)) { print "<h2>$day</h2>\n"; print "<dl>\n"; for $chan (qw(HBO SHOWTI)) { $formdata = join('&', 'timezone=PST', "dayAll=$day", 'TimeAll=All', 'categAll=all', "chan0=$chan", ); $request = new HTTP::Request('POST', 'http://www.tv1.com/cgi-win/search2.exe/', $headers, $formdata ); $response = $ua->request($request); next unless $response->isSuccess; for ($response->content =~ /^(<DT>.*\n(?:<DD>.*\n)?)/mig) { next unless /Stonehenge/i; print; } } print "</dl>\n"; } print "</body></html>\n"; exit 0; sub day { my @time = localtime time + $_[0]*86400; $time[4]++; sprintf("%02d/%02d/%02d", @time[4,3,5]); }
    目次

    ●LWP (libwww)モジュールを利用した例

    Q: I need to re-direct a form request to another URL, but I can't seem to do it when it is a forms POST. Is there anything I can do? A: With regard to redirection of transactions, he HTTP specification states: "The action required can sometimes be carried out by the user agent without interaction with the user, but it is strongly recommended that this only take place if the method used in the request is GET or HEAD." So the usual strategy of sending a 30x status code along with a location directive will not work, at least for most browsers. But if you decide it is required anyway, it is possible to accept the request and perform the redirection in your CGI program. NOTE: This will not work for requests needing authorization, unless you supply the authorization header as a part of the CGI. Here is a skeleton script, using the powerfull LWP (libwww) modules. #!/usr/bin/perl -wT use LWP; # The LWP module, main sub-module UserAgent use HTTP::Date; # For the MIME-compliant date function sub errorbox; # Routine to print HTML error and exit # Get the form data - use your favorite library instead. read(STDIN, $formdata, $ENV{CONTENT_LENGTH}) or errorbox("Read of STDIN failed"); $date = time2str(time); # From the HTTP::Date module # Set up the header information for the request $header = new HTTP::Headers 'Content-Type' => $ENV{CONTENT_TYPE}, 'MIME-Version' => '1.0', 'Date' => $date, 'Content-length' => $ENV{CONTENT_LENGTH}, 'Accept' => 'text/html', 'Orig-URI' => "http://" . $ENV{SERVER_NAME} . $ENV{SCRIPT_NAME}, ; # Set the location you want to redirect to. $redirect_url = 'http://localhost/cgi-bin/test-all-cgi'; $remote = new LWP::UserAgent; # Get the UserAgent object $request = new HTTP::Request # Get the Request object ('POST', $redirect_url, $header, $formdata); $tempfile = "/tmp/temphtml$$"; # Putting to a file for # this example, there are # other options including # an anonymous subroutine $response = $remote->simpleRequest($request,$tempfile); errorbox("Request for $redirect_url failed") unless($response); # Need to re-put the Content-type header, since our response # swallows it. Then open the temp file and print the HTML. # Real scripts should check the response return values and # check for bad cases print "Content-type: text/html\n\n"; open(OUT,$tempfile) or die "Couldn't read $tempfile: $!\n"; print <OUT>; close OUT; unlink $tempfile; exit; sub errorbox { my $title = shift; my @message = @_; print "Content-type: text/html\n\n"; print "<HEAD><TITLE>$title</TITLE></HEAD>\n"; print "<H1>$title</H1>\n"; for (@message) { print "$_\n" } exit; }
    目次

    ●CGI.pmもCGI-lib.plもない場合

    ◆Jim Owen氏による簡単なフォームとスクリプトサンプル(英語モード)。 <jim@charlie.webserve.com > Newsgroups: comp.lang.perl.misc Message-ID: <Pine.LNX.3.91.951010114746.22692A-100000@charlie.webserve.com> script: ..................................................................... #!/usr/local/bin/perl -w read(STDIN,$IN,$ENV{'CONTENT_LENGTH'}); #this is for post-get comes from $ENV{'QUERY_STRING'} $IN =~ s/\+/ /g; #change +'s to spaces %IN = (split(/[=&]/,$IN)); #put into associative array #print out return page: print "Content-type: text/html\n\n"; print '<HTML><BODY>Your input was: '; foreach $KEY(keys(%IN)){ print "<BR> $KEY equals : $IN{$KEY}"; } print '</BODY>'; ..................................................................... Form: ..................................................................... <HTML> <BODY> <FORM METHOD="post" ACTION="http://www.etc.your.script.pl"> foo: <INPUT NAME="foo"><BR> bar: <INPUT NAME="bar"><BR> <INPUT TYPE="submit"> </FORM> </BODY>
    目次

    ◆Peter Seibel氏によるサンプル(英語モード)。 <seibel@mojones.com> Newsgroups: comp.infosystems.www.authoring.html,comp.lang.perl.misc Message-ID: <45eho0$a96@kadath.zeitgeist.net> The form: :::::::::::::: :: foo.html :: :::::::::::::: <html> <head> <title></title> </head> <body> <form action="/cgi-bin/foo.pl" method="post"> <input name="foo" rows=10 cols=10> <input type=submit value="do it"> </form> </body> </html> The script: :::::::::::: :: foo.pl :: :::::::::::: #!/usr/local/bin/perl -w use strict; my($buffer, @pairs, $pair, $name, $value, %FORM); # this is the key line you were probably missing read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split '&', $buffer; # this stuff below stolen from somewhere I don't even know. foreach $pair (@pairs) { ($name, $value) = split('=', $pair); # Un-Webify plus signs and %-encoding $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; # Stop people from using subshells to execute commands $value =~ s/~!/ ~!/g; # Uncomment for debugging purposes # print STDERR "Setting $name to $value\n"; $FORM{$name} = $value; } print <<EOF; Content-type: text/html <html> <head> <title>FOO</title> </head> <body> EOF while (($name, $value) = each %FORM) { print "<p>$name is $value\n"; } print <<EOF; </body> </html> EOF __END__


    目次


    ご意見、ご要望は 電子メールまたは 投稿にお願い致します。

    ホームページへ戻る。