ScriptBasic講座
[最新コメントを上に]



1.最新コメントは上じゃないとヤダ!
今までで作った掲示板は、書き込むと下に書き込まれていくタイプの掲示板でした。
つまり、一番下がもっとも新しく、一番上がもっとも古いわけです。

これでは、一番最初に書き込まれた記事ばかりが注目されてしまいます。
現在、インターネット上で使われている掲示板の多くは、最新コメントが一番上のタイプです。






2.プログラム
-bbs14.bas-
#!/usr/bin/scriba

import cgi.bas

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

'読み込みを表示
CALL yomikomi

'プログラムはここまで
END

'読み込み部分
SUB yomikomi
        print "Content-Type: text/html; charset=euc-jp\n\n"

        print """
        <html><body>
        <form action="bbs14.bas" method="POST">
        お名前:<input type="text" name="onamae" size=20><br>
        Email:<input type="text" name="email" size=20><br>
        ▼コメント<br>
        <textarea name="comment" rows=4 cols=40></textarea><br>
        URL:<input type="text" name="url" value="http://" size=50><br>
        <input type="submit" value="送信">
        </form>
        """
                '読み込み部分(ファイルが存在する場合)
                IF FILEEXISTS("bbslog3.txt") Then
                                open "bbslog3.txt" for input as 1
                                        
                                        i=0

                                        '最後までループ
                                        while NOT(EOF(1))
                                                '配列data[i]に代入
                                                line input #1,data[i]
                                                i=i+1
                                        wend
                                close 1
                                
                                
                                'ループ開始
                                for a=i-1 to 0 STEP -1
                                        '配列data[a]を取り出し
                                        IF len(data[a])>0 Then
                                                        '分割:<>で分割
                                                        split data[a] by "<>" to onamae,comdata,email,url

                                                        'emailが書き込まれているか?
                                                        IF email <> "" Then 
                                                                print "お名前:<a href=\"mailto:",email,"\">",onamae,"</a>"
                                                        ELSE
                                                                print "お名前:",onamae
                                                        END IF


                                                        print "<br>",comdata,"<br>"

                                                        'urlがhttp://以外なら
                                                        IF url<>"http://\n" Then print "<a href=\"",url,"\">",url,"</a>"

                                                        print "<hr>"
                                        END IF
                                next



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


        print "</html></body>"

END SUB

'書き込み部分
SUB kakikomi
        '変数に代入
        comment=cgi::POSTParam("comment")
        onamae=cgi::POSTParam("onamae")
        email=cgi::POSTParam("email")
        url=cgi::POSTParam("url")

        'HTMLタグの置換
        comment=REPLACE(comment,"<","&lt;")
        comment=REPLACE(comment,">","&gt;")

        onamae=REPLACE(onamae,"<","&lt;")
        onamae=REPLACE(onamae,">","&gt;")
        email=REPLACE(email,"<","&lt;")
        email=REPLACE(email,">","&gt;")
        url=REPLACE(url,"<","&lt;")
        url=REPLACE(url,">","&gt;")

        '入力検査部分
        IF onamae="" then CALL errormes("お名前が記入されていません")
        IF comment="" then CALL errormes("コメントが記入されていません")

        '文字数検査
        IF len(comment)>1000 then CALL errormes("コメントが1000文字以下ではありません")
        IF len(onamae)>30 then CALL errormes("お名前が30文字以下ではありません")
        IF len(email)>64 then CALL errormes("Emailが64文字以下ではありません")
        IF len(url)>128 then CALL errormes("URLが128文字以下ではありません")

        '改行を<br>に
        comment=REPLACE(comment,"\r\n","<br>")
        comment=REPLACE(comment,"\r","<br>")
        comment=REPLACE(comment,"\n","<br>")

        '過去のデータをチェック
        IF FILEEXISTS("bbslog3.txt") Then

                        open "bbslog3.txt" for input as 1
                        '最後までループ
                        while NOT(EOF(1))

                                'checkに代入
                                line input #1,check

                                'checkが存在するか?
                                IF len(check)>0 Then
                                        '分割:<>で分割
                                        split check by "<>" to check_onamae,check_comdata,check_email,check_url
                                        IF comment=check_comdata then CALL errormes("過去に同じ内容の書き込みがあります")
                                END IF
                        wend
                        
                        close 1
        END IF



        '書き込み
        open "bbslog3.txt" for append as 1

        'ロック
        LOCK #1,write
        print #1,onamae,"<>",comment,"<>",email,"<>",url,"\n"

        'ロック解除
        LOCK #1,release
        close 1
        
        print "Location:http://127.0.0.1/cgi-bin/bbs14.bas\n\n"
        END
END SUB


'errormesサブルーチン
SUB errormes(errmessage)
        'メッセージを出力
        print "Content-Type: text/html; charset=euc-jp\n\n"
        print "<html><body>",errmessage,"</body></html>"
        'ここでプログラム終了
        END
END SUB

かなり長いプログラムでややこしいですが、変更箇所は、読み込み部分のみです。
その部分だけ以下に抜き出しました。

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

                        '最後までループ
                        while NOT(EOF(1))
                                '配列data[i]に代入
                                line input #1,data[i]
                                i=i+1
                        wend
                close 1
                
                
                'ループ開始
                for a=i-1 to 0 STEP -1
                        '配列data[a]を取り出し
                        IF len(data[a])>0 Then
                                        '分割:<>で分割
                                        split data[a] by "<>" to onamae,comdata,email,url

                                        'emailが書き込まれているか?
                                        IF email <> "" Then 
                                                print "お名前:<a href=\"mailto:",email,"\">",onamae,"</a>"
                                        ELSE
                                                print "お名前:",onamae
                                        END IF


                                        print "<br>",comdata,"<br>"

                                        'urlがhttp://以外なら
                                        IF url<>"http://\n" Then print "<a href=\"",url,"\">",url,"</a>"

                                        print "<hr>"
                        END IF
                next



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

配列を使っていますが、気を楽にしてやってみましょう。今急いで配列の仕組みを理解する必要はありません。
今は逆順に表示する為の仕組みとでも思っておいてください。配列が理解できなくて挫折してしまったら元も子もありません。

それでは簡単な解説です。
bbslog3.txtが存在した場合、open命令でbbslog3.txtをinputで開きます。
変数iに0を代入、whileで1行ずつ抜き出します。line input #1,data[i]でdata配列の要素iに取得したデータを入れています。i=i+1でiの値を更新していきます
1回目はi=0なのでdata[0]に、2回目はdata[1]に、という形でdata配列に代入していきます。
for a=i-1 to 0 STEP -1でまずaにiが入ります。そしてdata[i]を表示します。STEP -1というのはaの値を1ずつ引いていくという意味です
配列の[]内(添え字)は1始まりではなく0から始まりますので1引く必要があります。


▼参考リンク
配列を使おう




3.例で理解しよう!

▽bbslog3.txtの例
ウメ<>一回目の書き込み<>ume@ume<>http://ume-labo.com/scriptbasic/\n
ウメ<>二回目の書き込み<>ume@ume<>http://ume-labo.com/\n
ウメ<>三回目の書き込み<>ume@ume<>http://nw.ume-labo.com/\n

上記のような三行のデータを配列に入れてみましょう。(\nは改行を表します)
whileとline input #1,data[i]を使い、各行がdata配列に入っていきます。

▽配列dataの中身
添え字 要素
0 ウメ<>一回目の書き込み<>ume@ume<>http://ume-labo.com/scriptbasic/\n
1 ウメ<>二回目の書き込み<>ume@ume<>http://ume-labo.com/\n
2 ウメ<>三回目の書き込み<>ume@ume<>http://nw.ume-labo.com/\n
3 空白行

以上のように、data配列の中にデータが入りました。
whileループを抜けて、ファイルをcloseします。

さて、ここからが表示開始です。
for a=i-1 to 0 STEP -1
変数iにはコメントの件数(ファイルの行数)が入っています。
変数iの値(内容)は4です。aの値はi-1ですので3となります。配列の添え字は0始まりなので-1する必要があります
IF len(data[a])>0 Thenです。aの値は3です。data[3]が呼び出されますが、空白行ですので、len(data[a])>0は偽(FALSE)となり
Then以降は実行されません。そのままnextに達します。


STEP -1と指定されているのでaは4になるのではなく、逆に2になります。
IF len(data[a])>0 Thenでdata[2]の要素(中身)を確認します。ウメ<>三回目の書き込み<>ume@ume<>http://nw.ume-labo.com/\nですので
len(data[a])は57を返します。>0を満たしていますので、真(TRUE)となりThen以降が実行されます。
この先は通常の表示処理と同じです。data[2]の中身をsplitで分解、表示します。

nextに達するとSTEP -1でaをさらに-1します。aは1となります。
これを繰り返し、STEPが0になるまで、繰り返します。
0になると繰り返しを抜けて、終了です。

bbs13.basで表示した場合 bbs14.basで表示した場合

今回作ったbbs14.basでは三回目の書き込みが一番上に来ていることが確認できます。

戻る

ウメ研究所