ScriptBasic講座
[最初の掲示板]



1.書き込み部分
まずは1行だけ書き込める掲示板を作ってみましょう。

-bbs1.bas-
#!/usr/bin/scriba

import cgi.bas

'commentが送信されているか?
IF cgi::POSTParam("comment") <> undef Then

        'commentが存在する場合書き込み

        open "bbslog.txt" for append as 1
        print #1,cgi::POSTParam("comment"),"\n"
        close 1
END IF

print "Content-Type: text/html; charset=euc-jp\n\n"

print """
<html><body>
<form action="bbs1.bas">
<input type="text" name="comment" size="40">
<input type="submit" value="送信">
</form>
</html></body>
"""

▼実行結果


まだ、書き込み部分だけです。

1行目の#!/usr/bin/scribaはScriptBasicの位置です。
次のimport cgi.basはフォームからデータを入力する場合などに必要です。
この二つはCGIを書くときのおまじないとでも思ってください。

 '以降はコメントです。'より後ろは無視されます。

IFがありますので条件分岐です。cgi::POSTParam("comment")がundef以外の場合、THEN以降を実行する
プログラムになってますが、cgi::POSTParam("comment")はundefを返す為、THEN〜END IFの間は実行されません。
print "Content-Type: text/html; charset=euc-jp\n\n"以降のprintでHTMLを出力しています。

では、このテキスト入力欄に何か文字を、例えば12345を入力し、送信したらどうなるでしょうか?
今度はcgi::POSTParam("comment")はundefを返しません。cgi::POSTParam("comment")
フォームから送られた12345を表示する為です。
cgi::POSTParam()関数の"comment"という識別名は<input type="text" name="comment" size="40">で指定されていますね。
cgi::POSTParam()関数はPOST方式でフォームから送信されたデータを読み込みます。


IF内の実行ですopen命令でbbslog.txtを追記用に開いています。print #1,で送られてきたデータを書き込み、最後に\nを書きます。
\nは改行をあらわします。closeでファイルを閉じます。後は、通常通りフォームを表示して終わりです。

適当に書き込んでみて、bbslog.txtを開いてみてください。ちゃんと書けていたら成功です。

▼参考リンク
POSTを使おう
ファイルの取り扱い





2.読み込み部分の制作
読み込み部分を追加しましょう。

-bbs2.bas-
#!/usr/bin/scriba

import cgi.bas

'commentが送信されているか?
IF cgi::POSTParam("comment") <> undef Then

        'commentが存在する場合書き込み
        open "bbslog.txt" for append as 1
        print #1,cgi::POSTParam("comment"),"\n"
        close 1
END IF

print "Content-Type: text/html; charset=euc-jp\n\n"

print """
<html><body>
<form action="bbs2.bas" method="POST">
<input type="text" name="comment" size="40">
<input type="submit" value="送信">
</form>
"""

'読み込み部分(ファイルが存在する場合)
IF FILEEXISTS("bbslog.txt") Then
        open "bbslog.txt" for input as 1

        '最後までループ
        while NOT(EOF(1))
                'comdataに代入
                line input #1,comdata
                'comdataが存在すれば表示
                IF len(comdata)>0 Then print comdata,"<hr>"
        wend
        close 1

ELSE
        print "ファイルがありません"
END IF

print "</html></body>"
前半はbbs2.basにファイル名が変わった以外はbbs1.basとほぼ同じです。

▼実行サンプル
1回目の書き込み
あいうえを
avegegeghe
ehjiejhtoiejh

上記のように書き込んだときの表示サンプルです。





後ろに読み込み部分を追加しました。
IF FILEEXISTS("bbslog.txt") Thenとあります。
FILEEXISTS("bbslog.txt")はbbslog.txtが存在すれば真(TRUE)を返します。
IFは条件式が真の時、THEN以降を実行しますのでファイルが存在する場合のみTHEN〜END IFまでを実行するという意味です。
 
 open "bbslog.txt" for input as 1でファイルを読み込みモードで開いています。
 inputの場合はoutputなどと違い、事前に対象ファイルを制作しておかないとエラーとなってしまいます。
 FILEEXISTS("bbslog.txt")でファイルがあるかどうか調べているのはこのためです。
 
 EOF(1)はファイルの終端に達していれば真を返します。NOT()は()内を反転させます。真の場合、偽になり偽の時は真になります。
 WHILEループは真の間繰り返す命令ですから、NOT()で偽を真にする必要があります。

 EOF(番号) ファイル終端かどうか調べる
  番号:openで指定した番号

 NOT(データ) ビットを反転する


終端でない場合:EOF(1)は偽を返す   → NOTで偽を真にする → 真なので繰り返し、行読み取り処理に入る
ファイル終端の場合:EOF(1)は真を返す → NOTで真を偽にする → 偽なのでこれで繰り返しを抜ける

   line input #1,comdataでcomdataに代入します。
   IF len(comdata)>0 Thenは空白行対策です。bbs1.basのように各行の後ろに\n(改行コード)をつけるタイプの書き込みでは
   最終行は必ず空白行となっている筈です。その時に<hr>などのタグを表示してしまうのはちょっと都合が悪いです。
   comdataの文字数が0より大きいときのみprintを実行するようにしています。
   print comdata,"<hr>"、print命令でcomdataの内容を表示しています。最後の<hr>は罫線を示すHTMLタグです







3.ファイルLOCK
CGIプログラムは常に不特定多数の人によりアクセスされます。
誰がいつアクセスするかなんて予測はできません。まったく同じタイミングでアクセスされることもあるでしょう。
複数の人が同時にファイル書き込みをすると、ファイルが破損してしまいます。
そこで登場するのがファイルロックです。
一度ファイルロックされると、ファイルロックを解除するまで他の人はファイルにアクセスできなくなります。
ファイルロックはアクセス数にかかわらず、CGIには必ず搭載することを推奨します。


-bbs3.bas-
#!/usr/bin/scriba

import cgi.bas

'commentが送信されているか?
IF cgi::POSTParam("comment") <> undef Then
        'ロック
        LOCK #1,write

        'commentが存在する場合書き込み
        open "bbslog.txt" for append as 1
        print #1,cgi::POSTParam("comment"),"\n"
        
        'ロック解除
        LOCK #1,release
        close 1
END IF

print "Content-Type: text/html; charset=euc-jp\n\n"

print """
<html><body>
<form action="bbs3.bas" method="POST">
<input type="text" name="comment" size="40">
<input type="submit" value="送信">
</form>
"""

'読み込み部分(ファイルが存在する場合)
IF FILEEXISTS("bbslog.txt") Then
        open "bbslog.txt" for input as 1

        '最後までループ
        while NOT(EOF(1))
                'comdataに代入
                line input #1,comdata
                'comdataが存在すれば表示
                IF len(comdata)>0 Then print comdata,"<hr>"
        wend
        close 1

ELSE
        print "ファイルがありません"
END IF

print "</html></body>"


ファイルロックの方法はLOCK #1,writeLOCK #1,releaseを追加するだけです。
LOCK #1,writeでロックしLOCK #1,releaseでロックを解除しています
危険なのは書き込み時ですので、読み込み時はロックしていません。

戻る

ウメ研究所