
新しくCGIアプリケーションに対応したクラスが装備されています。入出力もカプセル化されて便利になっています。基本的な使い方を示しますのでご参照下さい。もちろん、このクラスを使わなくても、今までどおりのCGIも作れます。その際は以下に進んで下さい。
1.はじめに 最近では、ウィンドウズでも様々なWWWサーバが使えるようになってきました。ネットスケープやマイクロソフトのサーバなど広く使われています。その他にも各社からサーバがでています。いずれもCGIがサポートされていると思います。Program sample
uses Windows;
begin
Writeln('Content-type:text/plain');
Writeln('');
{内容を示すこの2行は必須です}
Writeln('こんにちは。Delphiで CGIです');
end.
これでCGIができます。「コンソールアプリケーション」のチェックボックスを選んでからコンパイルします。後はできあがったEXEファイルを、WEBサーバのCGIのディリクトリに転送すれば出来上がりです。
*リクエストの種別を知る部分*
var
nsize,nbsize:integer;
lpname,lpbuffer:pchar;
REQUEST:string;
begin
nsize:=255;
lpname:='REQUEST_METHOD';{この文字はサーバの解説を参照してください}
lpbuffer:=stralloc(nsize);
nbsize:=getenvironmentvariable(lpname,lpbuffer,nsize);
REQUEST:=strpas(lpbuffer);
strdispose(lpbuffer);
if REQUEST='POST' then
post{POSTの時のコードを記述}
else
get;{GETの時のコードを記述}
end;
*何バイトのデータがきているかを知る部分* var nsize,nbsize,contentlength:integer; lpname,lpbuffer:pchar; REQUEST:string; begin nsize:=255; lpname:='CONTENT_LENGTH';{この文字はサーバの解説を参照してください} lpbuffer:=stralloc(nsize); nbsize:=getenvironmentvariable(lpname,lpbuffer,nsize); contentlength:=strtoint(strpas(lpbuffer)); ............つぎにデータを解釈しながら文字列を読み込みます。ただし漢字コード変換は行っていません。
*送られてきた文字の読み込み*
var
moji:integer;
c:char;
intwork1,intwork2:integer;
CONTENT:string;{グローバル変数にしておくと便利かもしれません}
begin
moji:=1;
while moji<=contentlength do{入力されたバイト数だけ}
begin
read(c);{一文字ずつ読み込む}
inc(moji);
if c='%' then
{「%B9」のように「%」のついた文字は16進法で送られてきたコードなので、これを1文字に戻すための操作}
{この部分についてはさらに洗練されたコードにできるはずですが、著者の体力不足からこのままにしておきます}
begin
read(c);{1文字目}
inc(moji);
intwork1:=ord(c);
if intwork1<60 then
intwork1:=intwork1-48
else
intwork1:=intwork1-55;
read(c);{2文字目}
inc(moji);
intwork2:=ord(c);
if intwork2<60 then
intwork2:=intwork2-48
else
intwork2:=intwork2-55;
c:=chr(intwork1*16+intwork2);
end;
CONTENT:=concat(CONTENT,c);{1文字ずつ結果に加えて行く}
end;
..........
*データベースから1件だけ検索して、表として出力する部分*
var
CONTENT:string;{グローバル変数として、フォームの入力結果がこの「CONTENT」に入っているものとします}
procedure dbwrite;
var
Table1:TTable;
Datasource1:TDatasource;
DBEdit1:TDBEdit;
DBEdit2:TDBEdit;
begin
{オブジェクトの作成}
Table1:=ttable.create(application);
Datasource1:=tdatasource.create(application);
DBEdit1:=tdbedit.create(application);
DBEdit2:=tdbedit.create(application);
{プロパティの設定}
Table1.databasename:='MYDATABASE';{BDEで alias を作っておくと簡単}
Table1.tablename:='address.dbf';
Table1.indexname:='index1';{すばやい検索をするにはインデックスの作成が必要}
datasource1.dataset:=table1;
dbedit1.datafield:='name';
dbedit1.datasource:=datasource1;
dbedit2.datafield:='address';
dbedit2.datasource:=datasource1;
{検索実行}
table1.active:=true;
table1.setkey;
table1.findnearest([CONTENT]);
{表示}
writeln('<TABLE BORDER=2 CELLPADDING=3>');
writeln('<TR><TH>氏名</TH><TH>住所</TH></TR>');
writeln('<TR><TD>'+dbedit1.text+'</TD><TD>'+dbedit2.text+'</TD></TR>');
end;
なお、この方法ではローカルのデータベースへのアクセスはうまくゆきますが、リモートのデータベースアクセスはうまく行かないという連絡もありました。リモートのデータベースとの接続には時間がかかるため、CGIが起動するたびに毎回接続するよりも、常時接続するようなプログラムを走らせておいて、CGIがサーバとそのプログラムとの間の中継のみを行うようにした方が効率的と思います。(ここまでくるとプログラムはかなり複雑になりますが・・・)