Delphi for PHPを使い倒す!

Delphi for PHPを使い倒す!(中編)

データベースコンポーネントの使い方

はやしつとむ
アナハイムテクノロジー株式会社

2009/10/29

簡単DBアプリ作成−レコードの追加(1)

 さて、次に新しいレコードを追加できるにようにしてみます。

 まず、追加・更新用のフォームを1つ作成して、そこに必要なコンポーネントを配置・設定します。

 メインメニューから[新規作成]−[フォーム]を実行して新しいフォームを追加します。

●追加・更新用フォーム

  • Caption = Simple DB App
  • DocType = dtXHTML_1_0_Strict
  • Encoding = Unicode(UTF-8)
  • Name = form_edit

 ボタンを2つ、ラベルを4つ、エディットを3つ、コンボボックスを1つ配置して、以下のようにプロパティを設定します。ラベルのCaptionは画面のようにして下さい。

ラベルのCaption

●Button1

  • Caption = OK

●Button2

  • Caption = Cancel

●Edit1

  • Name = EDT_product

●Edit2

  • Name = EDT_price

●ComboBox1

  • Name = CMB_seasoning

●Edit3

  • Name = EDT_start_date

 それでは、呼び出し側のsimple_db_app.phpのButton2(Add new)にイベントハンドラを設定しましょう。IDEからボタンをダブルクリックして、以下のコードを追加します。

       function Button2Click($sender, $params)
       {
         global $dm_main;
         if($dm_main->db->Connected == false)
         {
           $this->show_alert('データベースに接続して下さい');
           return false;
         }
         $_SESSION['cmd'] = 'add_new';
         redirect('simple_db_edit.php');
       }

 ここでは、データベースへの接続をチェックして、もし接続していない場合には警告の文字列を表示するようにしています。

 show_alert()メソッド内では、Labelクラスのインスタンスを新たに生成して、Ownerを設定せずにParentだけを指定しています。Ownerはコンストラクタの引数で指定するのですが、ここにフォームを指定した場合には、このラベルはOwnerのComponents配列に登録されてシリアライズの対象となります。つまり、永続的なコンポーネントになります。

 しかし、今回は一時的に表示するだけで処理が正常に行われた場合はこのラベルは不要になるため、Parentだけを指定してフォームのControls配列に登録されるのみにとどめました。

       function show_alert($caption)
       {
            $Label = new Label(); //一時的なものなのでオーナーはなし
            $Label->Name = 'Label_alert';
            $Label->Caption = $caption;
            $Label->Top = $this->DBGRID_main->Top + $this->DBGRID_main->Height + 16;
            $Label->Left = 16;
            $Label->Width = $this->DBGRID_main->Width;
            $Label->Parent = $this;
            $Label->ParentColor = false;
            $Label->Font->Color = '#FF0000';
            return false;
       }

簡単DBアプリ作成−レコードの追加(2)

 次に、Button2のクリックで呼び出されたsimple_db_edit.php側でフォームのOnShowイベントハンドラを設定します。セッションで渡される$_SESSION['cmd']がadd_newだった場合には、フォームの各コンポーネントの値を初期化し、mod_rowが渡された場合にはセッションから変更前の値を各コンポーネントにセットするようにしておきます。

       function form_editShow($sender, $params)
       {
         switch($_SESSION['cmd'])
         {
           case 'add_new':
             $this->EDT_product->Text = '';
             $this->EDT_price->Text = '';
             $this->CMB_seasoning->ItemIndex = 'S';
             $this->DTP_start_date->Text = '';
             break;
           case 'mod_row':
             $this->EDT_product->Text = $_SESSION['product'];
             $this->EDT_price->Text = $_SESSION['price'];
             $this->CMB_seasoning->ItemIndex = $_SESSION['seasoning'];
             $this->DTP_start_date->Text = $_SESSION['start_date'];
             break;
         }
       }

 それでは、編集時に現在の値をDBGridで選択された行から取得して、form_editに渡すためにはどうしたらよいでしょうか。

 まずは、DBGridのJavaScriptイベントのOnRowChangedにイベントハンドラを設定します。また、このイベントハンドラ内で使用するHiddenFieldコンポーネントを1つform_mainに追加して以下のように設定しておきます。

 また、このHiddenFieldの値をフォームの表示時にリセットする必要があるので、form_mainのOnShowイベントハンドラも以下のように設定します。

●HiddenField1

  • Name = HDF_selected_id
       function DBGrid1JSRowChanged($sender, $params)
       {
         ?>
         //DBGridの選択された行をHiddenFieldにセットする
         //
         //DBGridの選択中の行からidを取得する
         var selected_id = DBGRID_main.getTableModel().getValue(0, DBGRID_main.getFocusedRow());

         //idをHIDDEN_FIELDにセットする
         document.getElementById("HDF_selected_id").value = selected_id;
         //
         <?php
       }

       function form_mainShow($sender, $params)
       {
         $this->HDF_selected_id->Value = null;
       }

 こうすることで、ユーザーの操作によってDBGrid上で行が選択された場合には、HDF_selected_idに行の第1カラムの値が設定されます。この場合では、menuテーブルのidが設定されるわけです。データのidが取得できればそれを基にして処理を進めることが可能ですね。

 Button3のイベントハンドラを以下のように設定します。データセット内で、指定のidのデータを探してそれがあれば、各カラムの値をセッションに保存して、simple_db_edit.phpを呼び出します。cmd = mod_rowも忘れずに指定しておきます。

       function Button3Click($sender, $params)
       {
          global $dm_main;
          if($dm_main->db->Connected == false)
          {
            $this->show_alert('データベースに接続して下さい');
            return false;
          }
          if($dm_main->qry->Active == false) $dm_main->qry->open();
          $_SESSION['id'] = null;
          $dm_main->qry->first();
          while ($dm_main->qry->EOF == false)
          {
            if ($dm_main->qry->Fields['ID'] == $this->HDF_selected_id->Value)
            {
              $_SESSION['id'] = $dm_main->qry->Fields['ID'];
              $_SESSION['product'] = $dm_main->qry->Fields['PRODUCT'];
              $_SESSION['price'] = $dm_main->qry->Fields['PRICE'];
              $_SESSION['seasoning'] = $dm_main->qry->Fields['SEASONING'];
              $_SESSION['start_date'] = $dm_main->qry->Fields['START_DATE'];
              break;
            }
            $dm_main->qry->next();
          }
          if($_SESSION['id']==null)
          {
            $this->show_alert('変更する商品を選択して下さい');
            return false;
          }

          $_SESSION['cmd'] = 'mod_row';
          redirect('simple_db_edit.php');
       }

簡単DBアプリ作成−レコードの追加(3)

 さて、ここまででsimple_db_app.phpからsimple_db_edit.phpへの呼び出し側の処理はすべて完了しました。次は、simple_db_edit.php側でのデータの登録/キャンセルの処理です。キャンセルボタンの処理は簡単ですね。セッションのcmdだけクリアしておいて、simple_db_app.phpへ戻ります。

       function Button2Click($sender, $params)
       {
         $_SESSION['cmd']=null;
         redirect('simple_db_app.php');
       }

 データを登録する、OKボタンの処理は以下のようになります。配列$dataに各カラムの値をセットしたら、dm_mainのadd_menu()、mod_menu()の各メソッドを呼んでから、セッションのcmdをクリアして、simple_db_app.phpへ戻ります。

       function Button1Click($sender, $params)
       {
         $data = array();
         $data[] = $this->EDT_product->Text;
         $data[] = $this->EDT_price->Text;
         $data[] = $this->CMB_seasoning->ItemIndex;
         $data[] = $this->DTP_start_date->Text;

         global $dm_main;
         switch($_SESSION['cmd'])
         {
           case 'mod_row':
             $data['id']=$_SESSION['id'];
             $dm_main->mod_menu($data);
             break;
           case 'add_new':
             $dm_main->add_menu($data);
             break;
         }
         $_SESSION['cmd']=null;
         redirect('simple_db_app.php');
       }

 実際にデータを登録するdm_mainのメソッドは以下のようになります。事前にパラメータクエリを設定してあるので、Paramsに$dataを指定して、execute()するだけです。今回は手抜きで値のチェックはしていませんが、パラメータクエリなのでセキュリティ的な観点からはSQLインジェクションを防げていますね。

       public function add_menu($data)
       {
         $this->db->Open();
         $this->qry_insert->Params = $data;
         $this->qry_insert->execute();
       }

       public function mod_menu($data)
       {
         $this->db->Open();
         $this->qry_update->Params = $data;
         $this->qry_update->execute();
       }

 さて、今回はDelphi for PHP 2.0でデータベースにアクセスするアプリケーション作成法を簡単に紹介しましたが、いかがだったでしょうか。

 次回は、今回のアプリケーションを拡張してPHPExcelを利用した帳票の出力と、Webブラウザ側での値のチェックを行うFormValidatorコンポーネントの使い方などを解説します。

 また、VCL for PHPのオブジェクトのSerialize/UnSerializeの機構とプロパティの実現方法と使い方などにも触れたいと思います。なんだか盛りだくさんで、終わる感じがしませんが、Delphi for PHP 2.0で皆さんがハッピーなWebアプリケーションを生み出す一助になれば幸いです。

 調子に乗って、Delphi for PHPのメーリングリストも始めました。ご興味のある方はぜひご参加ください。

 なお、前回、筆者が指摘したVCL for PHPの不具合ですが、エンバカデロ・テクノロジーズの高橋智宏さんがコミットしてくれました。こちらのURLのRev.272が該当します。

prev
3/3
 

Index
データベースコンポーネントの使い方
  Page1
データベースコンポーネント
ネイティブか、それとも汎用か、それが問題だ!
InterBaseコンポーネントの機能追加
  Page2
簡単DBアプリ作成−サンプルデータベース
簡単DBアプリ作成−メインフォーム
簡単DBアプリ作成−データモジュール
簡単DBアプリ作成−コーディング
Page3
簡単DBアプリ作成−レコードの追加(1)
簡単DBアプリ作成−レコードの追加(2)
簡単DBアプリ作成−レコードの追加(3)

index Delphi for PHPを使い倒す!

 Coding Edgeお勧め記事
いまさらアルゴリズムを学ぶ意味
コーディングに役立つ! アルゴリズムの基本(1)
 コンピュータに「3の倍数と3の付く数字」を判断させるにはどうしたらいいか。発想力を鍛えよう
Zope 3の魅力に迫る
Zope 3とは何ぞや?(1)
 Pythonで書かれたWebアプリケーションフレームワーク「Zope 3」。ほかのソフトウェアとは一体何が違っているのか?
貧弱環境プログラミングのススメ
柴田 淳のコーディング天国
 高性能なIT機器に囲まれた環境でコンピュータの動作原理に触れることは可能だろうか。貧弱なPC上にビットマップの直線をどうやって引く?
Haskellプログラミングの楽しみ方
のんびりHaskell(1)
 関数型言語に分類されるHaskell。C言語などの手続き型言語とまったく異なるプログラミングの世界に踏み出してみよう
ちょっと変わったLisp入門
Gaucheでメタプログラミング(1)
 Lispの一種であるScheme。いくつかある処理系の中でも気軽にスクリプトを書けるGaucheでLispの世界を体験してみよう
  Coding Edgeフォーラムフィード  2.01.00.91


Coding Edge フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

>

Coding Edge 記事ランキング

本日 月間