職場実習5日目

引き続きperlCGI掲示板作成

CGIの処理部分とHTML表示部分を切り分ける

ある程度まとまった複数行表示箇所は、perlの場合複数行でまとめて書く事ができるが、HTML文の部分のみ外部ファイルとして用意したほうが、書式の編集や挿げ替えが容易になると思う。
ただ、問題はHTML文書内にあるperl変数名の扱いである。外部ファイルから読み込んだ文字列に含まれる変数名を後から展開する事はできるのだろうか。調べた結果、以下のサイトを見つける事ができた。
テキストファイル内の変数を展開して出力したい - 教えて!goo

ログファイルの中で特殊文字と普通に使われる文字を区別する

BBSログファイル内の特殊文字(<, >, &, ", 半角空白等)を「&nbsp;」などの文字表記に置き換えて保存する事で、HTML表記する際のHTMLタグとの混同を避けると同時に、ログファイル内で特別な使われ方をする区切り文字(タブ, <>, カンマ等)との混同を避ける。
パワーソフト・HTML特殊文字一覧

ログファイル書式を考える

単純な書式として考えられるのは、書き込み1件につき1行とし、パラメータ間を区切り文字で分ける方法。
(例)

日時<>名前<>Emailアドレス<>題名<>内容
日時(TAB)名前(TAB)Emailアドレス(TAB)題名(TAB)内容

ただ、この方法の場合、後から項目が増減した場合、それまでのログの書式も見直さなければならず、拡張性に欠けるのではないかと思う。
拡張性を求める場合、次のようなタグで記述するほうが優れているかも知れない。
(例)

<time>日時</time><name>名前</name><mail>Emailアドレス</mail><subject>題名</subject><message>内容</message>

ただし、この方法の場合、書き込みの追加処理はあまり変える必要はないが、ファイルから読み出してパラメータ毎に切り分ける処理が難しい。
区切り文字によって分ける方法は、1件のデータをsplit文1つで切り分けられる利点があるのに対し、タグで囲む方法だと、split文で単純に分ける事ができず、区切り文字に正規表現を使う他に、マッチング文字列も一緒に取得する必要がある。

    my @mydatas = split(/<(.+?)>(.*?)<\/\1>/, $myline);
    my %myhash = ();
    for (my $mycount = 1; $mycount < @mydatas; $mycount += 3) {
        my $mydatakey = $mydatas[$mycount];
        my $mydatavalue = $mydatas[$mycount + 1];
        $myhash{$mydatakey} = $mydatavalue;
    }

上のソースでは、1件のデータ($myline)を1項目の書式パターン(<項目名>項目内容)で区切り、
項目と項目の間の空文字列と、項目名と項目内容をまとめて配列(@mydatas)に入れており、配列から項目名と項目内容を取り出し、ハッシュに格納し、1件のデータとして扱う。配列の中身は以下のようになる。

$mydatas[0] : 
$mydatas[1] : time
$mydatas[2] : 日時
$mydatas[3] : 
$mydatas[4] : name
$mydatas[5] : 名前
$mydatas[6] : 
$mydatas[7] : mail
$mydatas[8] : Emailアドレス
$mydatas[9] : 
$mydatas[10] : subject
$mydatas[11] : 題名
$mydatas[12] : 
$mydatas[13] : message
$mydatas[14] : 内容
$mydatas[15] : 

配列の要素は周期3で「空要素、項目名、項目内容、空要素…」と規則的に並んでいるので、それに合わせて項目名と項目内容を取り出す必要がある。

0    3    6    9    12    15   
1 time 4 name 7 mail 10 subject 13 message
2 日時 5 名前 8 Emailアドレス 11 題名 14 内容

取り出した部分(色の付いた部分)が丁度ハッシュになる。

ログなどのデータをSQLで管理する

実際に掲示板を動かすとなると、色々なファイルを用意する必要が出てくるし、いくつものファイルを管理するとなると処理が繁雑になるかも知れない。そこで、SQLでデータを全て管理する方法を考えてみた。
SQLを使うデータベースとしてはMySQLOraclePostgreSQL等があるが、今回はPostgreSQLを使ってみる。
商用データベースに負けないPostgreSQL
PostgreSQLをコマンドラインで操作する
PostgreSQLをプログラムで操作する
PostgreSQLはパッケージマネージャーを使えば簡単にインストールできた。suコマンドでpostgresアカウントでログインした後、データベースの初期化とテーブル作成を行ったが、Perlインターフェイスの導入部分でつまづいた。サイトに書かれている手順通りにソースを入手しインストールを試みたが、インストールされているPostgreSQLのバージョンが違い、サイトに書かれているバージョンのソースを入手できなかったため、導入を断念。MySQLに乗り換えようと調べた矢先、次のページを見つけた。
PerlでMySQL操作CGIを作ろう(1/4)
DBD/DBIモジュールは既にインストールされていたが、Data-ShowTableがインストールされていない模様。
早速パッケージマネージャーで探して見るも、見付からない。パッケージそのものが用意されていないらしい。
仕方がないので、Data-ShowTable-3.3.tar.gzをダウンロードして、インストールしたところ、うまく導入された模様。perlからのアクセスに成功した。ただし、日本語が文字化けしてしまい、文字コードが分からないので、Encode::Guessライブラリを使って、内部コードに変換する事で問題無く表示できるようになった。

サイトの構想を固める

前日、自分はSS(ショートストーリー)投稿サイトを作るというアイデアを思いついたが、まだ細かい部分の構想が固まらず、それで進めていいのか決められずにいる。何とかして明日までに決めなければならない。
仕組みとしては、次のようなものを考えることができる。

  • 会員登録した投稿者がSSを新しく書いたり内容を変えたりできる。
  • 投稿者はSSにパスワードを設定でき、パスワードは複数ユーザー間で共有できる。
  • SSは最小単位を「節(セクション)」とし、節単位でログファイルを保持する。
    • 節ごとに画像ファイルを1枚までアップロードし、挿絵として貼り付ける事ができる。
    • 節ごとに挿絵の位置などの書式を決める事ができる。
  • 節を関連付けるグループを作ることができる。
    • グループ単位は下から順に「章(チャプター)」と「部(パート)」、「巻(ブック)」、「作品(シリーズ)」。
    • どの上位グループにも属さない節があってもよい。章と部、巻も同じ。
  • 節と各グループの設定はSQLデータベースで管理する。
  • グループ間のツリー構造もSQLデータベースで管理する。

後は、もっと細かい部分まで詰めていき、仕様書として書き起こせば形になるかも知れない。