ScriptBasic講座
[サブルーチンで整理しよう]



1.書込み部分・読み込み部分・エラー部分の3つにわけよう

プログラムの行数も100行を突破し少しずつわかりにくくなってきました。
わかりやすくプログラムを書くためにここで、書込み部分・読み込み部分・エラー部分の三つにわけましょう。

-bbs10.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="bbs10.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

                '最後までループ
                while NOT(EOF(1))
                        'dataに代入
                        line input #1,data

                        'dataが存在するか?
                        IF len(data)>0 Then
                                '分割:<>で分割
                                split data 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
                wend
                close 1
        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()
                IF len(onamae)>30 then CALL errormes()
                IF len(email)>64 then CALL errormes()
                IF len(url)>128 then CALL errormes()

                '改行を<br>に
                comment=REPLACE(comment,"\r\n","<br>")
                comment=REPLACE(comment,"\r","<br>")
                comment=REPLACE(comment,"\n","<br>")
                
                '書き込み
                open "bbslog3.txt" for append as 1

                'ロック
                LOCK #1,write

                print #1,onamae,"<>",comment,"<>",email,"<>",url,"\n"
                
                'ロック解除
                LOCK #1,release
                close 1
END SUB


'errormesサブルーチン
SUB errormes
        'メッセージを出力
        print "Content-Type: text/html; charset=euc-jp\n\n"
        print "<html><body>入力データにエラーが存在します</body></html>"
        'ここでプログラム終了
        END
END SUB

書き込み部分のサブルーチン名はkakikomiです。
読み込み部分はyomikomiです。
エラー表示処理用のサブルーチンの名前はerrormesですね。

このCGIプログラムはIF cgi::POSTParam("comment") <> undef Then CALL kakikomiでcommentが送信されているか判断します。
送信されていなければFALSEですので、そのまま通過し、サブルーチンyomikomiを実行します。

サブルーチンyomikomiでは掲示板の書込みフォームや記事(ログ)を表示しています。
END SUBに到達すると、再び呼び出した部分(CALL yomikomi)に戻ります。次の命令はENDです。
このENDはプログラムとしてみるのであれば必要ありませんが、下はサブルーチンです。
人間がパッと見ただけではここで終わりかどうかわかりません。
「プログラムはここで終わりだよ」とわかりやすくする為、ENDを書きました。


もし書込みの場合はIF cgi::POSTParam("comment") <> undef Then CALL kakikomiでkakikomiサブルーチンを実行します。
kakikomiサブルーチンでは書き込み処理をし、書込みが正常に終了すると呼び出し元に戻ってきます。
次はyomikomiサブルーチンに移動し、掲示板を表示します。呼び出し元に戻ると次はEND命令です。






2.errormesサブルーチンをもう少し親切に
errormesサブルーチンはエラー時にエラーメッセージを表示し、終了するサブルーチンですが、
入力データにエラーが存在しますを表示するだけでは親切設計とは決していえません。
そこで何にエラーがあるのか出力することにします。


サブルーチンには引数というものがあり、データを自由に伝えることが出来ます。

CALL errormes("コメント")

SUB errormes(errmessage)

print "Content-Type: text/html; charset=euc-jp\n\n"
print "<html><body>",errmessage,"にエラーが存在します</body></html>"
'ここでプログラム終了
END

ENDSUB


こうすることで、「コメントにエラーが存在します」と表示することが可能です。
サブルーチンの()内にあるものを引数と呼び、,(カンマ)で区切ることにより何個でも伝えられます。
一番左の引数を引数1と呼び、一つ右を引数2と呼びます。もっとも上記のプログラムは引数1しかありませんが・・・。




3.プログラミング
-bbs11.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="bbs11.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

'最後までループ
while NOT(EOF(1))
'dataに代入
line input #1,data

'dataが存在するか?
IF len(data)>0 Then
'分割:<>で分割
split data 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
wend
close 1
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>")

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

'ロック
LOCK #1,write

print #1,onamae,"<>",comment,"<>",email,"<>",url,"\n"

'ロック解除
LOCK #1,release
close 1
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

▼お名前欄に31文字書いた場合の実行結果



呼び出し部分(CALL erromes())の()内、つまり引数1にエラーメッセージを書いています。
サブルーチンが呼び出され、変数errmessageにエラーメッセージが代入されます。
それを表示しただけです。

戻る

ウメ研究所