CodeZine(コードジン)

特集ページ一覧

FileMakerとPHPによるWebアンケートフォームの作成(中編)

第9回 PHPによるFileMakerのカスタムWeb公開 - (2)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2008/03/06 20:25

この連載では、システム開発において採用が増えつつある「FileMaker」というデータベースソフトウェアについて、最前線で活躍するエンジニアがリレー形式でその魅力を紹介します。第9回は3部構成で、アンケートフォームを作成しながら、FileMaker Server 9より実装された「PHPによるカスタムWeb公開機能」を解説します。中編。

はじめに

 前回は、FileMaker API for PHPの基本的な解説およびアンケートフォームのFileMaker部分を作成しました。今回は、いよいよFileMaker API for PHPを使ったWebページの作成に入ります。

 作成したWebアンケートデータベースから対象のアンケートを検索して、テーマやリード、質問や回答を読み込み、アンケートフォームとして表示させると言うところまでを解説していきたいと思います。API for PHPを使ったFileMakerからのレコードの検索、関連データの操作が今回のテーマです。

FileMaker API for PHPの概要

 具体的なコーディングに入る前に、まずFileMaker API for PHPの基本的な考え方を解説しておきます。

 FileMaker API for PHPはオブジェクト指向で開発されており、データベースの操作はクラス(オブジェクト)としてまとめられています。実行したい操作に応じてオブジェクトを作成し、各クラスに用意されている関数(メソッド)を利用しながらデータベースを操作していきます。

 用意されている主なクラスは以下のものになります。

主なクラス
クラス   操作内容
FileMakerデータベース FileMaker データベースへの接続、プロパティの設定
コマンド FileMaker_Command
FileMaker_Command_Add
FileMaker_Command_Compound_Find
FileMaker_Command_Delete
FileMaker_Command_Dupulicate
FileMaker_Command_Edit
FileMaker_Command_Find
FileMaker_Command_FindAll
FileMaker_Command_FindAny
FileMaker_Command_FindRequest
FileMaker_Command_PerformScript
レコード追加、
レコード削除、
レコード複製、
レコード編集、
レコード検索、
スクリプトの実行
レイアウト FileMaker_Layout データベースレイアウトからの情報取得
レコード FileMaker_Record レコードデータの操作
フィールド FileMaker_Field 定義されているフィールドの情報取得
関連セット FileMaker_RelatedSet 関連データの操作
結果 FileMaker_Result 検索や登録、編集、削除などコマンド系のクラスを実行した場合のレコードの処理
エラー FileMaker_Error,FileMaker_Error_Validation 上の結果でエラーが発生したかとうかの確認やエラー処理

 例えばデータベースからレコードを検索する場合の操作概要は次のようになります。

  1. FileMakerクラスを用いてデータベースに接続。
  2. 接続するデータベースを指定し、アカウントやパスワードをセットする。
  3. コマンドクラスを用いて検索条件を指定し、検索を実行。
  4. 結果クラスを用いて、対象レコードの取得を行う。
  5. レコードクラスを用いて、各レコードのデータを取り出す。
  6. 3でエラーが発生した場合(検索結果がないなど)、エラークラスを用いてエラー処理を行う。

 各クラス(オブジェクト)の役割と、それぞれに用意されている関数(メソッド)を理解すれば、今どんな処理がしたいのかによって、何をすればいいのか理解できるようになると思います。

アンケートフォーム画面のコーディング

 それではコーディングに入ります。まずはユーザーがアクセスした際に表示されるアンケートフォームの画面を作っていきます。

 アンケートフォームを表示する基本的な流れは次のようになります。

  1. FileMakerから対象のアンケートを検索して取得する。
  2.  
    アクセス日が対象期間内のデータで有効のものを検索する。1件のみ対象としたいので、開始日と終了日を降順でソートして1件目に最新のものがくるようにして、1件目のみ抽出する。
     
  3. 抽出したアンケートからタイトルやリード、質問や回答(ポータル内のデータ)を取得。
  4.  
  5. FileMakerから値一覧のデータを取得する。
  6.  
  7. 1、2、3でデータベースから情報を取得できた場合は、アンケートフォーム画面に取得したデータを展開する。
  8.  
  9. 1でアンケートを取得できなかった場合はエラー画面を表示する。

 ファイル構成は、上の1、2、3を処理する「index.php」、アンケートフォームを表示する「enquete.php」、エラー画面を表示する「enquete_error.php」とします。ロジック部分「index.php」と表示部分「enquete.php」「enquet_errror.php」を分けることによって、相互にメンテナンスや管理がしやすくなると思います。

 次のようになります。

http://serverName/FileMaker/
                  FileMaker.php
                  index.php
                  enquete.php
                  enquete_error.php

Webアンケートデータベースから対象のアンケートを検索

 まず、1のアンケート抽出の箇所は次のような記述になります。

ソース1 index.php - (1)
<?php

//文字コード指定 ※1
header("Content-Type: text/html;charset=utf-8");

//APIのインクルード ※2
include_once('FileMaker.php');

//FileMakerクラスを用いてFMに接続する。 ※3
$fm = new FileMaker();
$fm->setProperty('database', 'WEBアンケート');
$fm->setProperty('hostspec', 'http://localhost');
$fm->setProperty('username', 'web');
$fm->setProperty('password', 'enquete');
//アンケートを検索するため、コマンドクラスで検索用のインスタンスを作成。
// ※4
//引数にはレイアウト名を渡す。
$findCommand =& $fm->newFindCommand('アンケート詳細');
//検索条件の指定。(有効なアンケートで、対象期間にあてはまるもの)※5
$findCommand->addFindCriterion('有効',1);
$findCommand->addFindCriterion('開始日','...'.date('m/d/Y'));
$findCommand->addFindCriterion('終了日',date('m/d/Y').'...');
//ソート条件の指定。(開始日と終了日の降順) ※6
$findCommand->addSortRule('開始日', 1, FILEMAKER_SORT_DESCEND);
$findCommand->addSortRule('終了日', 2, FILEMAKER_SORT_DESCEND);
//検索実行 ※7
$result = $findCommand->execute();
  1. 作成したPHPファイルが文字コードUTF-8で記述されていることを明示するために、PHPのheader関数を使って文字コードを出力するようにしています。
  2.  
  3. FileMaker API for PHPを読み込みます。
  4.  
  5. 変数$fmFileMakerクラスのインスタンスが作成されます。setProperty()関数を使ってデータベース名やアカウント情報などを設定し、データベースに接続します。
  6.  
  7. FileMakerクラスに用意されているコマンドクラス呼び出しの関数を用いて検索用クラスのインスタンスを作成します。検索時に使用する関数はnewFindCommand()です。上では変数$findCommandに検索用オブジェクトが返るようにしています。
  8.  
  9. コマンドクラス(検索用)に用意されている検索条件追加のaddFindCriterion()関数を使って検索条件を指定します。検索対象のフィールド名と、検索条件を指定します。上のように検索演算子を付与して検索することもできます。
  10.  
    上の場合、開始日がアクセス日(当日)より以前で、終了日がアクセス日より以後にあるもので、有効にチェックが入っているものを検索条件として指定しています。通常のFileMakerでの検索で利用する範囲検索の検索演算子「…」を検索文字列に連結させています。
  1. コマンドクラス(検索用)に用意されているソート条件指定のaddSortRule()関数を使ってソート順を指定します。ソート対象のフィールド名、ソート順、ソートルール(昇順・降順・値一覧順)を指定します。上では開始日と終了日の順でそれぞれ降順にソート条件を指定しています。
  2.  
  3. コマンドクラス(検索用)に用意されている検索実行のexecute()関数を用いて検索を実行します。検索結果を、$result変数に返るようにします。

 上のように、クラスのインスタンスを作成して(上ではFileMakerクラスの$fm、検索コマンドクラスの$findCommand、検索結果クラスの$resultが作成されたインスタンスになります)、後はそれぞれのクラスに用意されている関数を、インスタンスに対して実行していきます。インスタンス名->関数名という構文がAPI for PHPでの操作の基本となります。

データベースへの検索実行後の処理

 次に、上の検索実行処理を受けてのレコード処理の記述です。

ソース2 index.php - (2)
//ソース1の続き
//検索実行
$result = $findCommand->execute();

//検索実行後の処理。結果オブジェクト($result)が
//エラーオブジェクトかどうかを判断する。※8
if(FileMaker::isError($result)){
//エラーが発生している場合の処理。

    //エラーメッセージを取得
    $error_mes = $result->getMessage();
    
    //エラーページを読み込んで表示する。
    include_once('enquete_error.php');

}else{
//検索成功時の処理 ※9
    
    //1件目のレコードを取得。(すべてのレコードを取得する場合は、
    //getRecord()メソッドを利用する)
    $record = $result->getFirstRecord();
    //ポータルデータのアンケート質問のデータを取得。※10
    $questions = $record->getRelatedSet('アンケート質問');
    
    //FMの回答詳細レイアウトのオブジェクトを取得して、
    //年代と性別の値一覧のデータを取得。※11
    $layout = $fm->getLayout('回答詳細');
    $ages = $layout->getValueList('年代');
    $sexs = $layout->getValueList('性別');
    
    //アンケートフォームを表示。※12
    include_once('enquete.php');

}
  1. 検索実行時にエラーが発生したかどうかは、isError()関数を使って判断します。エラーが発生している場合は、エラー処理を行います。ここではエラー処理はエラークラスのgetMessage()関数を利用して、エラーメッセージを取得、エラー表示画面「enquete_error.php」を読み込むという形にしています。
  2.  
  3. エラーが発生していない(検索結果がある)場合は、結果クラスのgetFirstRecord()関数を使って取得したレコードの1件目のデータを取得します。取得したレコードは、レコードオブジェクトとして$recordに返ります。
  4.  
  5. 取得したレコードの関連データ(ポータルのデータ)を取得します。結果クラスのgetRelatedSet()関数を使って関連データを取得します。関数の引数は取得する関連テーブルのテーブル名です。取得したデータは、レコードオブジェクトの件数分の配列として$questionsに返ります。
  6.  
  7. FileMakerクラスのレイアウト参照関数getLayout()を用いて、FileMakerの回答詳細に設定している値一覧「年代」と「性別」のデータを取得します。レイアウトクラスのgetValueList()関数を使って、それぞれの値一覧のデータを取得します。データは配列で返ります。
  8.  
  9. アンケートフォームの表示画面「enquete.php」を読み込みます。

改行コードで区切られた回答データをラジオボタンに展開

 次に、上で取得したデータをアンケートフォームに展開していくことになります。ここでのポイントの一つに、上の3で取得した関連データのフィールド「回答種類」のデータを、Webページで選択形式(ラジオボタン)で表示するように処理を行う必要があります。

 回答種類のデータは改行ごとに回答データが登録されている形になっていますので、PHPのexplode関数を使って、改行区切りで配列データに変換し、ラジオボタンに展開するようにします。

 Webページでこの処理が簡単に行えるように、カスタム関数を作ります。「index.php」の上の方に記述しましょう。

ソース3 index.php - (3)
<?php

//文字コード指定 ※1
header("Content-Type: text/html;charset=utf-8");

//フィールドデータを値一覧にするための関数。
//展開するデータと、フォーム名を引数に渡す。 ※13
function changeRadio($data,$name){
    if(!empty($data)){
        //改行コードを区切りにして配列に収める。※14
        $valueList = explode("\n",$data);
        echo "<p>";
        //配列に収めたデータを、ラジオボタンとして出力。※15
        foreach($valueList as $value){
            echo '<input type="radio" name="'.$name.
'" value="'.$value.'">'.$value;
        }
        echo "</p>\n";
    }

}

//APIのインクルード
include_once('FileMaker.php');
  1. 関数changeRadioに、改行を含むフィールドのデータと、Webフォームにセットするフォーム名の値を引数で渡すようにします。
  2.  
  3. フィールドのデータをexplode関数を使って改行区切りで配列に変換します。
  4.  
  5. 配列に変換されたフィールドのデータ$valueListを、foreach関数を使って個々に取り出し、Webフォームのラジオボタンにして出力します。

アンケートフォーム表示画面 その1

 次に、アンケートフォーム画面「enquete.php」のコーディングです。この画面が実際にユーザーに表示される画面となります。まずはフォームの上半分タイトルやリードなどを表示する箇所からです。

ソース4 enquete.php - (1)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><?=$record->getField('WEBタイトル')?></title>
</head>

<body>
<h1><?=$record->getField('WEBタイトル')?></h1>
<p><?=nl2br($record->getField('WEBリード'))?></p>
<form action="receive.php" method="post">
<input type="hidden" name="アンケートNo"
       value="<?=$record->getField('アンケートNo')?>" />
<p>氏名:<input type="text" name="氏名" value="" /></p>
<p>年代:<select name="年代">
<option value=""></option>
<?php
foreach($ages as $age){
    echo '<option value="'.$age.'">'.$age.'</option>';
}
?>
</select></p>
<p>性別:
<?php
foreach($sexs as $sex){
    echo '<input type="radio" name="性別" value="'.$sex.'">'.$sex;
}
?></p>
  1. Webページのタイトルと見出し・リードに、FileMakerから取得したフィールドの値をレコードクラスのgetField()関数を用いて表示させています。引数でフィールド名を指定します。また、このgetField()関数は、フィールドのデータにサニタイズ処理がされており、HTMLタグなどが変換されて表示されるようになっていますので(PHPのhtmlspecialchars関数を適用)、フィールドデータにHTMLタグが含まれていてもセキュリティ上問題になることはございません。フィールド内のHTMLタグなどをそのまま画面上に表示させたい場合は、getFieldUnencoded()関数を利用します。
  2.  
  3. このアンケートフォームの値を、「receive.php」に送信して処理をするようにformタグの値をセットします。
  4.  
  5. このアンケートフォームからFileMakerに送信される値は、[氏名]、[年代]、[性別]([質問明細No]、[回答])×質問の数、となります。[氏名]、[年代]、[性別]は回答見出しテーブルに登録し、[質問明細No]、[回答]は回答明細テーブルに登録するようにします。
  6.  
  7. 取得した年代と性別のデータを、foreach関数を使ってプルダウンやラジオボタンに展開します。

アンケートフォーム表示画面 その2

 次は、質問と回答の表示部分です。

ソース4 enquete.php - (1)
//ソース4の続き。
<?php
if(count($questions)){
    echo "<ul>\n";
    //質問と回答のデータを質問の数だけ展開する。 ※16
    foreach($questions as $question){
        echo "<li>".
            $question->getField('アンケート質問::質問')."</li>\n";
        //隠しタグで回答明細の明細Noにセットする質問Noを出力 ※17
        echo '<input type="hidden" name="質問回答['
.$question->getField('アンケート質問::質問No').'][no]" value="'
.$question->getField('アンケート質問::質問No').'">';
        //上で作成した関数に、フィールドのデータとフォーム名を
        //引数にしてラジオボタンに展開する。※18
        echo changeRadio($question->getField('アンケート質問::回答種類'),
        '質問回答['.$question->getField('アンケート質問::質問No').'][value]');
    }
    echo "</ul>\n";
}
?>
<p>
<input type="submit" name="_create" value="送信" />
<input type="reset" value="リセット" />
</p>
</form>
</body>
</html>
  1. 関連データのレコードオブジェクトの配列として返ってきているので、foreach関数を使ってそれぞれ個々のレコードのデータを取り出します。getField()関数を使ってフィールドの値を取り出します。フィールド名を指定する際は、テーブル名::フィールド名という正式名称で指定します。
  2.  
  3. 複数ある質問と回答のデータをFileMakerへの登録の際に処理しやすくするため、フォーム名を配列形式にセットします。

 登録先の回答明細の明細Noフィールドにはアンケート質問テーブルの質問No、回答明細の回答フィールドには、回答種類のデータをセットするようにします。その際のフォーム名は、明細Noは「質問回答[質問No][no]」、回答は「質問回答[質問No][value]」という形になるようにします。これにより、配列質問回答には、質問No分のデータがセットされ、さらにその中に明細Noと回答のデータがセットされるようにします。

 次のような形になります。

Array
(
    [質問回答] => Array
        (
            [質問No] => Array
                (
                    [no] => 質問No
                    [value] => 回答データ
                )
    )
)
  1. 上で作成したchangeRadioという自作関数を使い、フィールドのデータをラジオボタンに展開するようにします。フォーム名は配列形式になるようにしています。

 以上でアンケートフォームの画面は終了です。レコードの検索に成功してアンケートデータを展開した場合の画面イメージは次のようになります。

図22 アンケートフォーム
図22 アンケートフォーム

対象のアンケートが検索できなかった場合のエラー表示画面

 次に、アンケートの検索が失敗した場合のエラー画面を作成します。

ソース5 enquete_error.php
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>WEBアンケート</title>
</head>

<body>
<h1>WEBアンケート</h1>
<p>現在募集しているアンケートはございません。(<?=$error_mes?>)</p>
</body>
</html>

 エラーページにメッセージを表示させています。

 アンケートフォームアクセス時に、対象のアンケートがない場合のエラー画面のイメージは次のようになります。

図22-1 アンケートフォームエラー画面
図22-1 アンケートフォームエラー画面

 以上で、アンケートフォームの表示部分は終了です。

次回について

 次回は、このフォームデータからのFileMakerへの登録処理、そして回答データの集計処理の作り方を解説します。

  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 堀 直樹(ホリ ナオキ)

    大学卒業後入社の企業にて、趣味のFileMaker使いからなりゆきで社内のシステム担当となり社内システムの開発に孤軍奮闘する。その後ソフトハウスに転職してFileMakerによるシステム開発に従事し、現在は株式会社キクミミにて数々の企業のシステムを開発する。PHPによるカスタムWebでのシステム構築...

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5