Delphiでお手軽プログラミング

Delphiでお手軽プログラミングメニュー

DelphiでチャットWebアプリケーションを作成する(WindowsのCGI)

MariaDB+Apache(又はIIS)+DelphiでCGIを作成してチャットWEBアプリケーションを作成する


MariaDB(又はMySQL)にチャット用データベースとテーブルを作成する

以下SQLにてデータベース「db_chat」を作成します。
-- データベース db_test の作成
Create database db_chat character set utf8;

-- db_testにユーザ user パスワード password でユーザー作成と権限を与える
Grant all on db_chat.* to user@localhost identified by 'password' with grant option;
Flush privileges;

-- データベースにテーブルを作成
Create table db_chat.t_chat(
  id int auto_increment, 
  nickname varchar(30), 
  remark varchar(255), 
  regdate datetime default CURRENT_TIMESTAMP, 
  primary key(id)
);



MariaDB(又はMySQL)に接続するDLLファイルをパスの通ったフォルダに入れる

インターネット等から「libmariadb.dll」又は「libmysql.dll」ファイルをダウンロードして
c:\windows
等のパスの通ったフォルダに入れる。


Delphiを起動して新規作成を行う

Delphiを起動し、ファイル→新規作成→その他・・・をクリックします。


左ペインの「Web」を選択し、右ペインの「Webサーバーアプリケーション」をクリックし「OK」ボタンをクリックします。



「次へ」をクリックします。



今回は「CGIスタンドアロン実行可能ファイル」を選択します。IISやApacheでCGIとして動作させることができます。完了ボタンをクリックします。



すべて保存(SHIFT+CTRL+S)を押してフォルダを作成し、 ユニットをデフォルトの「WebModuleUnit1.pas」プロジェクトを「chat.dproj」で保存します。
Shift+F12を押してフォームの一覧を表示します。
WebMobule1(WebMobuleUni1.pas)を選択してOKボタンをクリックします。



右下ペインのパレットから、TFDConnectionを1つ、TFDQueryを2つドラッグします。



TFDConnection1を右クリックし「接続エディタ」をクリックします。



ドライバを「MySQL」にします。
Databaseを「db_chat」、User_Nameを「user」、Passwordを「password」、 Serverを「localhost」、CharacterSetを「utf8」と入力します。
「OK」ボタンを押して閉じます。



FDConnection1を左クリックして選択し、プロパティ「LoginPrompt」を[False]に設定します。



FDQuery1を右クリックし「クエリエディタ」をクリックします。「SQLコマンド」タブに以下SQLを入力し、OKボタンを押します。
select id,nickname,remark,regdate
from t_chat
order by id desc
limit 5


FDQuery2を右クリックし「クエリエディタ」をクリックします。「SQLコマンド」タブに以下パラメータSQLを入力し、OKボタンを押します。
insert into t_chat( nickname, remark )
  values( :nickname, :remark )



FDQuery2をクリックして選択した状態で左下ペインのオブジェクトインスペクタの「プロパティ」タブの [Params]プロパティの右端の[...]をクリックします。



「FDQuery2.Paramsの編集」ウィンドウが起動するので、「NICKNAME」をクリックして選択し、 オブジェクトインスペクタの「DataType」プロパティを[ftWideString]に設定します。
「REMARK」をクリックして選択し、オブジェクトインスペクタの「DataType」プロパティを「ftWideString」に設定します。



左上の「構造」ペインの[WebModule1]をクリックし、左下ペインの「プロパティ」タブの「Actions」プロパティの 右にある[...]をクリックする。



「WebModule1.Actionsの編集」ウィンドウが開くので、1行目の[DefaultHandler]を左クリックして選択し、 左下の「オブジェクト インスペクタ」ペインの「イベント」タブをクリックし、 [OnAction]イベントの右側をダブルクリックする。



ソースコードを記述する

unit WebModuleUnit1;

interface

uses
  System.SysUtils, System.Classes, Web.HTTPApp, FireDAC.Stan.Intf,
  FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf,
  FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys,
  FireDAC.Phys.MySQL, FireDAC.Phys.MySQLDef, FireDAC.ConsoleUI.Wait, Data.DB,
  FireDAC.Comp.Client, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf,
  FireDAC.DApt, FireDAC.Comp.DataSet;

type
  TWebModule1 = class(TWebModule)
    FDConnection1: TFDConnection;
    FDQuery1: TFDQuery;
    FDQuery2: TFDQuery;
    procedure WebModule1DefaultHandlerAction(Sender: TObject;
      Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
  private
    { private 宣言 }
  public
    { public 宣言 }
  end;

var
  WebModuleClass: TComponentClass = TWebModule1;

implementation

{%CLASSGROUP 'System.Classes.TPersistent'}

{$R *.dfm}

uses System.NetEncoding;

procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var html:string;
    nickname,remark:string;
    cc:TCookie;
const
    CRLF:string=#13#10;
begin
  //ニックネームのPOST値を取得
  nickname:=trim(Request.ContentFields.Values['nickname']);
  //発言のPOST値を取得
  remark  :=trim(Request.ContentFields.Values['remark']);
  if (nickname<>'') and (remark<>'') then
  begin
    //パラメータ クエリーにパラメータを設定して実行する
    FDQuery2.Params.ParamByName('nickname').Value:=nickname;
    FDQuery2.Params.ParamByName('remark').Value:=remark;
    FDQuery2.Prepare;
    FDQuery2.ExecSQL;
    remark:='';
  end;
  if nickname='' then
    nickname:=trim(Request.CookieFields.Values['nickname']);

  if nickname<>'' then
  begin
    cc:=Response.Cookies.Add;
    cc.Name:='nickname';
    cc.Value:=nickname;
    cc.Expires:=now+1/24;
    cc.Path:='/';
  end;

  Response.ContentType:='text/html; charset=UTF-8';
  html:=
    '<html><head>'+CRLF+
    '<script>'+CRLF+
    '  window.addEventListener("DOMContentLoaded",function(){'+CRLF+
    '    document.getElementById("remark").focus();'+CRLF+
    '  });'+CRLF+
    '</script'+CRLF+
    '</head>'+CRLF+
    '<body>'+CRLF;

  html:=html+
    '<table border="1">'+CRLF+
    '<tr><th>日時</th><th>ニックネーム</th><th>発言</th></tr>'+CRLF;
  //テーブルから発言一覧(最大5行)を取得する
  FDQuery1.Active:=True;
  if not FDQuery1.Eof then
  begin
    while not FDQuery1.Eof do
    begin
      html:=html+'<tr>'+CRLF;
      html:=html+
        '<td>'+FDQuery1.Fields[3].AsString+'</td>'+CRLF;
      html:=html+
        '<td>'+THTMLEncoding.HTML.Encode(FDQuery1.Fields[1].AsString)+
        '</td>'+CRLF;
      html:=html+
        '<td>'+THTMLEncoding.HTML.Encode(FDQuery1.Fields[2].AsString)+
        '</td>'+CRLF;
      html:=html+'</tr>'+CRLF;
      FDQuery1.Next;
    end;
  end;
  html:=html+'</table>'+CRLF;

  html:=html+
    '<form method="post" action="'+Request.ScriptName+'">'+CRLF+
    '<table>'+CRLF;
  html:=html+
    '<tr><td>ニック<br>ネーム:</td><td>'+
    '<input type="text" name="nickname" id="nickname" maxlength="10" '+
      'value="'+THTMLEncoding.HTML.Encode(nickname)+'">'+
    '</td></tr>'+CRLF;
  html:=html+
    '<tr><td>発言:</td><td>'+
    '<input type="text" name="remark" id="remark" maxlength="60" '+
      'size="60" value="'+THTMLEncoding.HTML.Encode(remark)+'">'+
    '</td></tr>'+CRLF;
  html:=html+
    '</table>'+CRLF+
    '<input type="submit" value="登録" />'+CRLF+
    '</form>'+CRLF;

  html:=html+'</body></html>';

  Response.Content:=html;
end;

end.

参考:

Postの値はRequest.ContentFieldsに入っています。Getの値はRequest.QueryFieldsに入っています。
Cookieの値はRequest.CookieFieldsに入っています。
Cookieの値を変更したり追加するにはResponse.Cookiesに追加します。


リリース ビルドに切り替える

IDE右上の「プロジェクト」ペインの chat.exeのビルド構成の[Release]をダブルクリックします。

(Debugビルドは最適化が無効でファイルサイズが大きく処理速度も遅くなります。Releaseビルドは最適化され処理速度が速くなりますがデバッグ実行はできません。)


コンパイルする

メニューバーの「プロジェクト」⇒「すべてのプロジェクトをビルト」をクリックします。

「cgi-bin」フォルダにコンパイルした「chat.exe」ファイルを配置する

C:\Users\[ユーザー名]\Documents\Embarcadero\Studio\Projects\vcl_web_mysql\Win32\Release
にあるファイル chat.exe ファイルを、

C:\Apache24\cgi-bin
等のApacheの cgi-bin フォルダにコピーする。(IISの場合は scripts フォルダ)


必要であれば、chat.exe ファイルを右クリックしてプロパティ⇒セキュリティタブから、Apache(又はIIS)を起動している ユーザーを追加して「読み取りと実行」権限を与える。

ブラウザを起動して実行してみる

ブラウザを起動してURLに
http://localhost/cgi-bin/chat.exe
と入力してEnterキーを押します。


「ニックネーム」と「発言」を入力して「登録」ボタンをクリックすると投稿できます。


Internal Application Error / 内部アプリケーションエラー
[FireDAC][Phys][MySQL]-314. ベンダ ライブラリ [libmysql.dll, libmariadb or libmysqld.dll] を読み込めません。 指定されたモジュールが見つかりません。 ヒント: PATH またはアプリケーションの EXE ディレクトリに含まれているか、x86 ビットであるかを確認してください。
と表示される場合は、「cgi-bin」フォルダに
「libmariadb.dll」又は「libmysql.dll」ファイルを 入れてみてください。

Copyright 2020 Mam