Perl/ActivePerl For UNIX/Linux/Windows
 
TryThe Homepage
初めてのCGI
CGI 研究室
ダイナミックCGI
ダウンロード
サービス
サーバ構築(Windows)
データベースアクセス
有料サービス
FAQ
お問い合わせ
このページを印刷
開発のコツ
当サイトがフリーで公開している多機能Perl専用ライブラリperl-lib.plを使用すれば、 誰にでも簡単にCGIを作成することができます。 このコーナーでは、簡単な掲示板を例にあげ1からCGIを作ってみます。 実際に1から作り上げるとなると、ある程度の機能を持ったテキストエディタが必要です。 Windowsのメモ帳でも不可能ではありませんが、ネッ途上にはフリーで公開されている高機能なエディタが有りますので、 各自入手してください。
  TaraPadの入手
フリーで公開されているテキストエディタは数多く存在しますが、 高機能で軽快に動作するTeraPadを使用します。Perlも意識して開発されていますので非常に便利です。
  1. TeraPadのダウンロード
    作者のページ「To Clip」 から最新版をダウンロードします。

  2. セットアップ
    lzh形式の場合は解凍するだけで完了です。TaraPad.exeを実行するだけです。
    動作を設定するには[表示]-[オプション]を選択します。

    「基本」設定はほとんど変更する必要は有りません。
    「文字の折り返し」を選択しなければ長い行でも自動的に折り返される事が有りませんので、 スクリプトだけでなく、データの編集にも快適です。


    「初期改行コード」を「LF」に設定しておけば、TaraPadで編集したスクリプトは、 FTPの「バイナリ」モードでアップロードしても動作します。
    万一「テキスト」モードでアップロードしても何の問題もありませんので、 「LF」に設定しておいた方が無難です。

  ホームページ作成ソフト
直接タグを書くことのできる方には必要有りませんが、今回は最も簡単に開発する方法をご紹介しますので、 「ホームページビルダー」、「フロントページ」、「Dreamweaver」等のホームページ作成ソフトをご用意ください。
  掲示板の作成
それでは、いよいよ掲示板の作成です。 学習ですので、すぐにサンプルをコピーするのではなく、ご自分で作成してみてください。
  1. フォームをデザインする
    まずは、ホームページ作成ソフトで投稿フォームを作成します。
    お名前
    メールアドレス
    件名
    コメント
    ホームページ作成ソフトなら簡単に作成できると思います。 項目は、自由に作成していただいて結構ですが、このサンプルでは「投稿者氏名」、 「メールアドレス」、「記事の題名」と「記事本文」です。 フォームフィールドが設定可能な場合は、この時点でお名前にはname、メールアドレスにはemail、 件名にはsubject、コメントにはcommentとフィールド名も設定しておきます。

  2. エディタに張り付け
    どのようなホームページ作成ソフトにもソースを表示する機能が有りますので、 ソース表示または、HTMLをすべて選択してコピーして、エディタ(TeraPad)に張り付けます。
    <html>
    <head>
    <meta http-equiv="Content-Type"content="text/html;charset=shift_jis">
    <title>新しいページ1</title>
    </head>
    <body>
    <form>
      <table border="1">
      <tr>
        <td align="center">お名前</td>
        <td><input type="text" size=24 name="name"></td>
      </tr>
      <tr>
        <td align="center">メールアドレス</td>
        <td><input type="text" size=63 name="email"></td>
      </tr>
      <tr>
        <td align="center">件名</td>
        <td><input type="text" size=63 name="subject"></td>
      </tr>
      <tr>
        <td align="center">コメント</td>
        <td><textarea name="comment" rows="7" cols="62"></textarea></td>
      </tr>
      </table>
      <input type="submit" value="書き込み">
    </form>
    </body>
    </html>
    筆者の場合は上記のように作成されていました。 ここから不必要なタグを削除しなければなりませんので<form>より上、</form>より下を削除します。
    <form>
      <table border="1">
      <tr>
        <td align="center">お名前</td>
        <td><input type="text" size=24 name="name"></td>
      </tr>
      <tr>
        <td align="center">メールアドレス</td>
        <td><input type="text" size=63 name="email"></td>
      </tr>
      <tr>
        <td align="center">件名</td>
        <td><input type="text" size=63 name="subject"></td>
      </tr>
      <tr>
        <td align="center">コメント</td>
        <td><textarea name="comment" rows="7" cols="62"></textarea></td>
      </tr>
      </table>
      <input type="submit" value="書き込み">
    </form>
    これで必要なフォームだけになりましたが、まだ、不必要なものがあります。 それは、2個以上続いたスペースとダブルクォーテーション(" )です。 TeraPadを使用すれば簡単に削除することができます。 メニューコマンドの置き換えを選択し、[検索する文字列]にスペースを2個打って、 [置換後の文字列]には何も指定せず、[すべて置換]ボタンを押します。 1個のスペースは、 タグのセパレータとして使用されていますので、2個以上続いたスペースだけを削除します。

    同様に[検索する文字列]に"を指定し、[置換後の文字列]には何も指定せず、 [すべて置換]ボタンを押すとダブルクォーテーションもすべて削除されます。
    <form>
    <table border=1>
    <tr>
    <td align=center>お名前</td>
    <td><input type=text size=24 name=name></td>
    </tr>
    <tr>
    <td align=center>メールアドレス</td>
    <td><input type=text size=63 name=email></td>
    </tr>
    <tr>
    <td align=center>件名</td>
    <td><input type=text size=63 name=subject></td>
    </tr>
    <tr>
    <td align=center>コメント</td>
    <td><textarea name=comment rows=7 cols=62></textarea></td>
    </tr>
    </table>
    <input type=submit value=書き込み>
    </form>
    ここまで出来れば、Perlの命令を追加します。 Perlの行の最後には「;」が必要ですので、これも置き換えで追加します。 [検索する文字列]に\nを指定、[置換後の文字列]には\\n";として置き換えます。 置き換えが完了するとすべての行の先頭にprint "を追加します。
    sub form {
      print "<formaction=startbbs.cgi method=POST>\n";
        print "<input type=hidden name=action value=regist>\n";
        print "<table border=1>\n";
        print "<tr>\n";
        print "<td align=center>お名前</td>\n";
        print "<td><input type=text size=24 name=name></td>\n";
        print "</tr>\n";
        print "<tr>\n";
        print "<td align=center>メールアドレス</td>\n";
        print "<td><input type=text size=63 name=email></td>\n";
        print "</tr>\n";
        print "<tr>\n";
        print "<td align=center>件名</td>\n";
        print "<td><input type=text size=63 name=subject></td>\n";
        print "</tr>\n";
        print "<tr>\n";
        print "<td align=center>コメント</td>\n";
        print "<td><textarea name=comment rows=7 cols=62></textarea></td>\n";
        print "</tr>\n";
        print "</table>\n";
        print "<input type=submit value=書き込み>\n";
      print "</form>\n";
    }
    出来上がった物を関数として呼び出せるようsub form {として宣言しています。 また、このフォームの[書き込み]ボタンが押された場合に呼び出されるCGIも設定しています。 とりあえずこのサンプルにはstartbbs.cgiと名づけました。 print "<input type=hidden name=action value=regist>\n"; は、隠しフィールドで実際には表示されず、 このフォームの[書き込み]ボタンが押された事をstartbbs.cgiに伝える働きをします。

  3. 初期設定部を作る
    ほとんどの場合初期設定部は同じでかまいません。
    #!/usr/local/bin/perl

    #日本語コード変換モジュール
    require 'jcode.pl';
    require 'perl-lib.pl';

    #---------------------------------------
    #メッセージを格納するデータファイル
    $datafile = 'startbbs.txt';
    #---------------------------------------
    #バックグランドの画像ファイル
    $bgimg = '';
    #---------------------------------------
    #バックグランドカラー
    $bg = '#300030';
    #テキストの文字色
    $text = '#FFFFFF';
    #リンク文字色
    $link = '#FFFF00';
    #Vリンク文字色
    $vlink = '#FFEE00';
    #Aリンク文字色
    $alink = '#FFEEDD';
    #フォントサイズ
    $fontsize = 11;
    #---------------------------------------
    #コメント最大記憶数
    $max = 100;
    #---------------------------------------
    #1ページに表示する件数
    $pagevew = 10;
    #---------------------------------------
    #時差
    $timelag = 0;
    #=======================================
    # 初期設定が必要なのはここまでです。
    #=======================================
    このコードをform関数の上に追加します。 もちろん先頭行にはPerlのパス、すぐ下にはjcode.plとperl-lib.plのパスが記述されています。 上記の設定では、startbbs.cgiと同じディレクトリにjcode.pl、perl-lib.plが存在するという設定になっています。

  4. メインルーチンの追加
    ここからがデータを書得したり、条件により処理を分岐するメインルーチンです。 最初は、時刻や、データを取得する関数を呼び出します。
    #=======================================
    # 初期設定が必要なのはここまでです。
    #=======================================
    #サーバから日付と時刻を取得する
    $ENV{'TZ'} = "GMT";
    $DATE = time + $timelag * 3600;
    $DATENOW = jst_time($DATE, 5);
    #CGIが呼び出された時の条件やデータを取得
    readparts('QUERY', '<>=', 'sjis');
    #データファイルの記事を取得
    @DATA = data_read($datafile);
    #HTMLのヘッダーを宣言
    html_head($bg, $text, $link, $vlink, $alink, $bgimg, 10, 10, '', $fontsize);
    #フォームを呼び出す
    &form();
    print "</body></html>\n";
    exit;
    sub form {
      print "<form action=startbbs.cgi method=POST>\n";
    青い部分が追加されたメインルーチンです。 メインルーチンの最後にはexit;を置くことを忘れないでください。 ここまでで実行して、フォームだけの掲示板は表示できます。

  5. 記事の保存
    フォームだけの掲示板が表示できるようになり、記事を記入して送信する事もできるようになりましたが、 フォームの[書き込み]ボタンを押しても記事は保存されません。 書き込み用のコードが無いのですから当然です。
    それではメインルーチンに書き込みコードを挿入しましょう。
    #データファイルの記事を取得
    @DATA = data_read($datafile);
    #呼び出し条件による分岐
    if ($QUERY{'action'} eq 'regist') {
      #フォームの[書き込み]ボタンが押されれば
      #現在までの記事の数を数える
      $count = @DATA;
      #最大記録数より多くなれば古い記事を削除
      if ($max <= $count) { pop(@DATA); }
      #新しい記事のコード番号を生成
      if ($count) {
        #最後に投稿された記事のコードに1プラスする
        %FIELD = fields($DATA[0]);
        $newcode = $FIELD{'code'} + 1;
      } else {
        #記事が1件もなければ最初のコードは1
        $newcode = 1;
      }
      #記録するデータのフォーマットを整える
      $value = join("\t",
        "code=$newcode",
        "date=$datenow",
        "name=$QUERY{'name'}",
        "email=$QUERY{'email'}",
        "subject=$QUERY{'subject'}",
        "comment=$QUERY{'comment'}",
        "\n"
      );
      #すべての記事の先頭に追加
      unshift(@DATA, $value);
      #サーバに保存
      data_save($datafile, @DATA);
    }
    #HTMLのヘッダーを宣言
    html_head($bg, $text, $link, $vlink, $alink, $bgimg, 10, 10, '', $fontsize);
    青い部分が追加されたメインルーチンです。 フォーム作成時にも解説しましたが、フォームの[書き込み]ボタンが押されると、 隠しフィールドでactionにはregistのデータが送信されています。 perl-lib.plのreadparts関数は、フォームから送られたデータは連想配列%QUERYに保存しますので、 フォームの[書き込み]ボタンが押されたのかを知るためには$QUERY{'action'}を調べ、 registなら書き込み処理を記述します。
    これでフォームに記事を記入して[書き込み]ボタンを押すとデータファイル「startbbs.txt」が作成され、 きちんと記事は保存されています。

  6. 記事表示イメージをデザインする 記事が投稿でき、保存されていても表示できなければ掲示板にはなりません。 次は記事を表示するイメージをホームページ作成ソフトでデザインします。 複数の記事はプログラムで表示できますので、デザインするのは1件の記事だけで結構です。
    ここに件名 お名前 メールアドレス 投稿日
    記事の本文
    投稿された項目は、「氏名」、「メールアドレス」、「件名」、「コメント」ですが、 投稿された日付も保存されていますので表示するようレイアウトを作成します。

  7. エディタに張り付け
    フォームのデザイン時同様に新しいエディタを開き、ソースを張り付けます。 筆者のホームページ作成ソフトでは次のように表示されました。
    <table border="1" width="448">
       <tr><td width="438">
       <table border="0" width="100%" cellspacing="0" cellpadding="4">
           <tr> <td bgcolor="#000080"><font color="#FFFFFF">ここに件名</font></td>
           <td bgcolor="#000080"><font color="#FFFFFF">お名前</font></td>
           <td bgcolor="#000080"><font color="#FFFFFF">メールアドレス</font></td>
           <td bgcolor="#000080" align="right"><font color="#FFFFFF">投稿日</font></td>
           </tr>
       </table>
       </td></tr>
       <tr><td width="438">
           <blockquote>
           記事の本文
           </blockquote>
       </td></tr>
    </table>
    ここにも、フォームの設計時同様不要なスペースとダブルクォーテーションが有りますので、 削除し、print文と、\n";を追加します。
    すると次のようなコードが完成します。
    print "<table border=1 width=448>\n";
    print "<tr><td width=438>\n";
    print "<table border=0 width=100% cellspacing=0 cellpadding=4>\n";
    print "<tr> <td bgcolor=#000080><font color=#FFFFFF>ここに件名</font></td>\n";
    print "<td bgcolor=#000080><font color=#FFFFFF>お名前</font></td>\n";
    print "<td bgcolor=#000080><font color=#FFFFFF>メールアドレス</font></td>\n";
    print "<td bgcolor=#000080 align=right><font color=#FFFFFF>投稿日</font></td>\n";
    print "</tr>\n";
    print "</table>\n";
    print "</td></tr>\n";
    print "<tr><td width=438>\n";
    print "<blockquote>\n";
    print "記事の本文\n";
    print "</blockquote>\n";
    print "</td></tr>\n";
    print "</table>\n";

  8. メインルーチンにコピー
    完成した記事を表示するコードをスクリプトのメインルーチンにコピーして張り付けます。 記事は、フォームの下に表示しますので、&form();の直後に張り付けてください。 単に張り付けただけではデータファイルの内容を表示することはできませんので、コードを追加します。
    &form();
    foreach (@DATA) {
       %FIELD = fields($_);
       print "<table border=1 width=100%>\n";
           print "<tr><td>\n";
           print "<table border=0 width=100% cellspacing=0 cellpadding=4>\n";
               print "<tr> <td bgcolor=#000080><font color=#FFFFFF>$FIELD{'subject'}</font></td>\n";
               print "<td bgcolor=#000080><font color=#FFFFFF>$FIELD{'name'}</font></td>\n";
               print "<td bgcolor=#000080><font color=#FFFFFF>$FIELD{'email'}</font></td>\n";
               print "<td bgcolor=#000080 align=right><font color=#FFFFFF>$FIELD{'date'}</font></td>\n";
               print "</tr>\n";
           print "</table>\n";
           print "</td></tr>\n";
           print "<tr><td>\n";
           print "<blockquote>\n";
           print "$FIELD{'comment'}\n";
           print "</blockquote>\n";
           print "</td></tr>\n";
       print "</table>\n";
       print "<br>\n";
    }
    print "</body></html>\n";
    exit;
    foreachは、ループ命令で@DATAの数だけ繰り返します。 fields関数は、perl-libの関数でキー=データ形式の文字列を連想配列に分解してくれます。 したがって、データ保存時に"name=お名前"で保存されていれば$FIELD{'name'}に名前が格納されるということです。 デザイン時に記入しておいたフィールドをこのフィールド変数に置き換えれば実際のデータが表示されるという仕掛けです。 これで、ひとまずは掲示板として動作します。 ただこれだけでは全ての記事が一度に表示され、百件にもなると大変な時間を要します。 そこで、指定した件数を表示したら[次のページ]ボタンを表示するようにしましょう。
    &form();
    #表示を開始する番号と終了番号を計算
    #[次のページ]が押されれば開始の番号を
    #前のページに表示した次から開始
    if ($QUERY{'next'}) { $start = $QUERY{'next'}; }
    $last = @DATA - 1;
    $end = $start + $pageview - 1;
    #表示件数よりデータが少なければ最後のデータ
    if ($end > $last) { $end = $last; }
    foreach ($start .. $end) {
       %FIELD = fields($DATA[$_]);
       print "<table border=1 width=100%>\n";
           print "<tr><td>\n";
           print "<table border=0 width=100% cellspacing=0 cellpadding=4>\n";
               print "<tr> <td bgcolor=#000080><font color=#FFFFFF>$FIELD{'subject'}</font></td>\n";
               print "<td bgcolor=#000080><font color=#FFFFFF>$FIELD{'name'}</font></td>\n";
               print "<td bgcolor=#000080><font color=#FFFFFF>$FIELD{'email'}</font></td>\n";
               print "<td bgcolor=#000080 align=right><font color=#FFFFFF>$FIELD{'date'}</font></td>\n";
               print "</tr>\n";
           print "</table>\n";
           print "</td></tr>\n";
           print "<tr><td>\n";
           print "<blockquote>\n";
           print "$FIELD{'comment'}\n";
           print "</blockquote>\n";
           print "</td></tr>\n";
       print "</table>\n";
       #最後に表示したデータがデータの最後でなければ
       #[次のページ]ボタンを表示する
       if ($end != $last) {
           $next = $end + 1;
           print "<input type=button value=次ページ onclick=\"location.href='startbbs.cgi?next=$next'\">\n";
       }
    }
    print "</body></html>\n";
    exit;
    やった〜...これで基本型の完成です。
    これで最低限度の機能を持った掲示板の完成です。 あとは、タイトル画像や、自動改行等のオプションを付けるだけです。

  9. オプションの追加
    【タイトル画像を付ける 】
    #HTMLのヘッダーを宣言
    html_head($bg, $text, $link, $vlink, $alink, $bgimg, 10, 10, '', $fontsize);
    #タイトル画像を表示
    print "<img src=title.gif>\n";

    #フォームを呼び出す
    &form();
    【自動改行 】
    print "<blockquote>\n";
    #自動改行
    $FIELD{'comment'} =~ s/\r/<br>/g;
    print "$FIELD{'comment'}\n";
    print "</blockquote>\n";
    【メールアドレスにリンクを付ける 】
    print "<td bgcolor=#000080><font color=#FFFFFF>";
    $FIELD{'email'} && print "<a href=mailto:$FIELD{'email'}>$FIELD{'email'}</a>";
    print "</font></td>\n";
    ここまでの完成品サンプルコードはこちら、 サンプルはこちらです。ご自分のコードと比較してみてください。
Copyright 2004 Terra. All rights reserved. No reproduction or republication without written