はじめに
前回は、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 | 上の結果でエラーが発生したかとうかの確認やエラー処理 |
例えばデータベースからレコードを検索する場合の操作概要は次のようになります。
FileMaker
クラスを用いてデータベースに接続。- コマンドクラスを用いて検索条件を指定し、検索を実行。
- 結果クラスを用いて、対象レコードの取得を行う。
- レコードクラスを用いて、各レコードのデータを取り出す。
- 3でエラーが発生した場合(検索結果がないなど)、エラークラスを用いてエラー処理を行う。
各クラス(オブジェクト)の役割と、それぞれに用意されている関数(メソッド)を理解すれば、今どんな処理がしたいのかによって、何をすればいいのか理解できるようになると思います。
アンケートフォーム画面のコーディング
それではコーディングに入ります。まずはユーザーがアクセスした際に表示されるアンケートフォームの画面を作っていきます。
アンケートフォームを表示する基本的な流れは次のようになります。
- FileMakerから対象のアンケートを検索して取得する。
- 抽出したアンケートからタイトルやリード、質問や回答(ポータル内のデータ)を取得。
- FileMakerから値一覧のデータを取得する。
- 1、2、3でデータベースから情報を取得できた場合は、アンケートフォーム画面に取得したデータを展開する。
- 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のアンケート抽出の箇所は次のような記述になります。
<?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();
- 作成したPHPファイルが文字コードUTF-8で記述されていることを明示するために、PHPの
header
関数を使って文字コードを出力するようにしています。 - FileMaker API for PHPを読み込みます。
- 変数
$fm
にFileMaker
クラスのインスタンスが作成されます。setProperty()
関数を使ってデータベース名やアカウント情報などを設定し、データベースに接続します。 FileMaker
クラスに用意されているコマンドクラス呼び出しの関数を用いて検索用クラスのインスタンスを作成します。検索時に使用する関数はnewFindCommand()
です。上では変数$findCommand
に検索用オブジェクトが返るようにしています。- コマンドクラス(検索用)に用意されている検索条件追加の
addFindCriterion()
関数を使って検索条件を指定します。検索対象のフィールド名と、検索条件を指定します。上のように検索演算子を付与して検索することもできます。
- コマンドクラス(検索用)に用意されているソート条件指定の
addSortRule()
関数を使ってソート順を指定します。ソート対象のフィールド名、ソート順、ソートルール(昇順・降順・値一覧順)を指定します。上では開始日と終了日の順でそれぞれ降順にソート条件を指定しています。 - コマンドクラス(検索用)に用意されている検索実行の
execute()
関数を用いて検索を実行します。検索結果を、$result
変数に返るようにします。
上のように、クラスのインスタンスを作成して(上ではFileMaker
クラスの$fm
、検索コマンドクラスの$findCommand
、検索結果クラスの$result
が作成されたインスタンスになります)、後はそれぞれのクラスに用意されている関数を、インスタンスに対して実行していきます。インスタンス名->関数名
という構文がAPI for PHPでの操作の基本となります。
データベースへの検索実行後の処理
次に、上の検索実行処理を受けてのレコード処理の記述です。
//ソース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'); }
- 検索実行時にエラーが発生したかどうかは、
isError()
関数を使って判断します。エラーが発生している場合は、エラー処理を行います。ここではエラー処理はエラークラスのgetMessage()
関数を利用して、エラーメッセージを取得、エラー表示画面「enquete_error.php」を読み込むという形にしています。 - エラーが発生していない(検索結果がある)場合は、結果クラスの
getFirstRecord()
関数を使って取得したレコードの1件目のデータを取得します。取得したレコードは、レコードオブジェクトとして$record
に返ります。 - 取得したレコードの関連データ(ポータルのデータ)を取得します。結果クラスの
getRelatedSet()
関数を使って関連データを取得します。関数の引数は取得する関連テーブルのテーブル名です。取得したデータは、レコードオブジェクトの件数分の配列として$questions
に返ります。 FileMaker
クラスのレイアウト参照関数getLayout()
を用いて、FileMakerの回答詳細に設定している値一覧「年代」と「性別」のデータを取得します。レイアウトクラスのgetValueList()
関数を使って、それぞれの値一覧のデータを取得します。データは配列で返ります。- アンケートフォームの表示画面「enquete.php」を読み込みます。
改行コードで区切られた回答データをラジオボタンに展開
次に、上で取得したデータをアンケートフォームに展開していくことになります。ここでのポイントの一つに、上の3で取得した関連データのフィールド「回答種類」のデータを、Webページで選択形式(ラジオボタン)で表示するように処理を行う必要があります。
回答種類のデータは改行ごとに回答データが登録されている形になっていますので、PHPのexplode
関数を使って、改行区切りで配列データに変換し、ラジオボタンに展開するようにします。
Webページでこの処理が簡単に行えるように、カスタム関数を作ります。「index.php」の上の方に記述しましょう。
<?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');
- 関数
changeRadio
に、改行を含むフィールドのデータと、Webフォームにセットするフォーム名の値を引数で渡すようにします。 - フィールドのデータを
explode
関数を使って改行区切りで配列に変換します。 - 配列に変換されたフィールドのデータ$valueListを、
foreach
関数を使って個々に取り出し、Webフォームのラジオボタンにして出力します。
アンケートフォーム表示画面 その1
次に、アンケートフォーム画面「enquete.php」のコーディングです。この画面が実際にユーザーに表示される画面となります。まずはフォームの上半分タイトルやリードなどを表示する箇所からです。
<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>
- Webページのタイトルと見出し・リードに、FileMakerから取得したフィールドの値をレコードクラスの
getField()
関数を用いて表示させています。引数でフィールド名を指定します。また、このgetField()
関数は、フィールドのデータにサニタイズ処理がされており、HTML
タグなどが変換されて表示されるようになっていますので(PHPのhtmlspecialchars
関数を適用)、フィールドデータにHTMLタグが含まれていてもセキュリティ上問題になることはございません。フィールド内のHTMLタグなどをそのまま画面上に表示させたい場合は、getFieldUnencoded()
関数を利用します。 - このアンケートフォームの値を、「receive.php」に送信して処理をするように
form
タグの値をセットします。 - このアンケートフォームからFileMakerに送信される値は、[氏名]、[年代]、[性別]([質問明細No]、[回答])×質問の数、となります。[氏名]、[年代]、[性別]は回答見出しテーブルに登録し、[質問明細No]、[回答]は回答明細テーブルに登録するようにします。
- 取得した年代と性別のデータを、
foreach
関数を使ってプルダウンやラジオボタンに展開します。
アンケートフォーム表示画面 その2
次は、質問と回答の表示部分です。
//ソース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>
- 関連データのレコードオブジェクトの配列として返ってきているので、
foreach
関数を使ってそれぞれ個々のレコードのデータを取り出します。getField()
関数を使ってフィールドの値を取り出します。フィールド名を指定する際は、テーブル名::フィールド名
という正式名称で指定します。 - 複数ある質問と回答のデータをFileMakerへの登録の際に処理しやすくするため、フォーム名を配列形式にセットします。
登録先の回答明細の明細Noフィールドにはアンケート質問テーブルの質問No、回答明細の回答フィールドには、回答種類のデータをセットするようにします。その際のフォーム名は、明細Noは「質問回答[質問No][no]」、回答は「質問回答[質問No][value]」という形になるようにします。これにより、配列質問回答には、質問No分のデータがセットされ、さらにその中に明細Noと回答のデータがセットされるようにします。
次のような形になります。
Array ( [質問回答] => Array ( [質問No] => Array ( [no] => 質問No [value] => 回答データ ) ) )
- 上で作成した
changeRadio
という自作関数を使い、フィールドのデータをラジオボタンに展開するようにします。フォーム名は配列形式になるようにしています。
以上でアンケートフォームの画面は終了です。レコードの検索に成功してアンケートデータを展開した場合の画面イメージは次のようになります。
対象のアンケートが検索できなかった場合のエラー表示画面
次に、アンケートの検索が失敗した場合のエラー画面を作成します。
<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>
エラーページにメッセージを表示させています。
アンケートフォームアクセス時に、対象のアンケートがない場合のエラー画面のイメージは次のようになります。
以上で、アンケートフォームの表示部分は終了です。
次回について
次回は、このフォームデータからのFileMakerへの登録処理、そして回答データの集計処理の作り方を解説します。