sironekotoroの日記

Perl で楽をしたい

Perlの絵本 第8章 CGIプログラミング サンプル

  • この本も長かった・・・ような。
  • 初版2005年の本なので書き方が古いように感じたり、use strict; use warnings;無かったりなところが不満と言えば不満
    • まぁ、Perlに本格的に手をつけて半年の自分が言うのもアレだけど
  • でも、過去の遺産の再活用、という観点で言えばとても役に立つなぁと。
    • 今時、PerlCGIちゃんと説明しているものってなかなか無いもの。
  • とくに、CGIがどうやってデータをやり取りしていたのかを体験できたのが本当に良かった。
    • GETとPOSTくらいは知っていたけど、環境変数を通じてデータのやり取りをしていた、ってのは知らなかった。20年くらい軽く疑問だったんで解けて嬉しい
      • 軽い疑問:解けなくても日常生活にまったく影響ない程度の疑問
  • ここで作ったサンプルCGIplackとかで動かしてみたい・・・あれ、その場合って書き込みテキストの場所とかパーミッションとかどうなるんだろう?
  • 解決する疑問がたくさんあるってのは幸せだわ

サンプルスクリプトCGI

  • うちの環境だと、投稿を反映させるのにリロードしなきゃダメだった。
  • あと、パーミッション設定が本当にめんどくて泣ける
#!/usr/bin/perl

# メインプログラム
%input = ( "TITLE" => "タイトルなし", "NAME" => "名前なし" );
$filename = "bbsdata.txt";    #書き込みデータ保存ファイル
&getString();                    #入力データの取得

print "Content-type: text/html;charset=UTF-8\n\n";
print "<html><head><title>掲示板</title></head>\n";
print "<body><center>\n";

&pageForm();                     #入力フォームの表示
&pageList();                     #書き込みデータの表示

# おまけ:環境変数の表示
foreach $key (keys %ENV){
    print "<b>$key</b>$ENV{$key}<br>\n";
}

print "</center></body></html>\n";

# 入力データの取得==========
sub getString {
    if ( $ENV{"REQUEST_METHOD"} eq "GET" ) {
        $str = $ENV{"QUERY_STRING"};
    }
    else {
        read( STDIN, $str, $ENV{"CONTENT_LENGTH"} );
    }
}

# デコード
$str =~ tr/+/ /;
$str =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("c",hex($1))/eg;

# 入力データの書き込み
foreach ( split( /&/, $str ) ) {
    my ( $key, $value ) = split( /=/, $_ );
    $value =~ s/</&lt;/g;       #「<」の変換
    $value =~ s/>/&gt;/g;       #「>」の変換
    $value =~ s/\r\n/<br>/g;    # 改行の変換
    if ( $value ne "" ) { $input{$key} = $value; }
}

# コメントが入力されていた場合
if ( $input{'COMMENT'} ne "" ) {

    # ファイルに書き込み
    open( FILE, ">>" . $filename ) || die "Error!\n";
    print FILE "$input{'TITLE'}:::$input{'NAME'}:::$input{'COMMENT'}\n";
    close(FILE);
}

# 入力フォームの表示==========
sub pageForm {
    print << "EOF";
  <FORM NAME = "FORM" ACTION="bbs.cgi" METHOD="POST">
  <FONT SIZE="+2">掲示板</FONT>
  <TABLE>
      <TR>
          <TD>名前</TD>
          <TD><INPUT TYPE="TEXT" SIZE="30" NAME="NAME"></TD>
      </TR>
      <TR>
          <TD>タイトル</TD>
          <TD><INPUT TYPE="TEXT" SIZE="30" NAME="TITLE"></TD>
      </TR>
      <TR>
          <TD>コメント</TD>
          <TD><TEXTAREA COLS="50" ROWS="5" NAME="COMMENT"></TEXTAREA></TD>
      </TR>
  </TABLE>
  <INPUT TYPE="SUBMIT" VALUE="書き込み">
  <INPUT TYPE="RESET" VALUE="クリア">
</FORM>
EOF
}

# 書き込みデータの表示==========
sub pageList {

    # ファイルが無い場合は終了
    unless ( -e $filename ) { return; }
    print "<HR>\n";
    print "<TABLE WIDTH=\"400\" BORDER=\"1\">\n";
    open( FILE, "<" . $filename ) || die "Error!\n";
    while (<FILE>) {
        chomp($_);
        my ( $title, $name, $comment ) = split( /:::/, $_ );
        print "\t<TR><TD>$title&nbsp;$name</TD></TR>\n";
        print "\t<TR><TD>$comment</TD></TR>\n";
    }
    close(FILE);
    print "</TABLE>\n";
}