ここまでFileMakerのCRUD実装方法を紹介した。一覧画面以外はコードのみの紹介だったためいまいちイメージしにくい地味な紹介記事になってしまっていたが、いよいよ今回から何回かに分けて画面を交えた解説に入っていこう。

CRUDの復習の意味で、単一テーブルによる簡単な画面構成をともなったWebアプリケーションを実装してみよう。対応する画面は次のとおり。

  • C: 新規登録画面
  • R: 一覧画面・詳細画面
  • U: 編集画面
  • D: 詳細画面から削除ボタン押下
  • その他: それぞれの処理正常終了時に表示するリプライ画面と、エラー時に表示するエラー画面

画面遷移図

今回はこのうち「新規登録画面」「一覧画面」の2画面について取りあげる。なお、MVCにもとづいた構成、詳細画面から一覧画面へ戻る際の位置といったいくつかの細かい機能は省略させていただくので、あらかじめご了承願いたい。また一度にFileMakerと通信する回数を極力減らすために本来は$_SESSIONなどを使用したほうが良い場面があるが、それはひととおり解説が終わった後で紹介させていただく。

CRUDの画面構成をともなったWebアプリケーションを実装するにあたって使用するファイル情報は次のとおり。

  • ファイル名: fxphp_crud_test.fp7
  • テーブル名: fxphp
  • レイアウト名: web_detail, web_list
  • フィールド名: 画像を参照

フィールド定義情報

値一覧をともなった新規登録画面

では実装に入る。まずは新規登録画面からだ。FileMaker上で組んだレイアウトをそのまま新規登録画面として採用してみよう。

レイアウト-web_detail

FileMakerのレイアウトと作成する画面の対応は次のとおり。

配置したフィールドの入力タイプ

  • FileMakerの編集ボックス: HTMLの<input type="text">に対応させる
  • FileMakerのドロップダウンリスト: HTMLの<select>に対応させる
  • FileMakerのチェックボックスセット: HTMLの<input type="checkbox">に対応させる
  • FileMakerのラジオボタンセット: HTMLの<input type="radio">に対応させる

また、各フィールドには次のような値を設定する。

配置したフィールドに設定する値一覧

  • f_history: valueLists_f_history
  • f_useVersion: valueLists_f_useVersion
  • f_useOS: valueLists_f_useOS

使用する値一覧情報

これを実装した結果は次のようになる。なお、ここでは登録完了画面や登録失敗画面も用意している。

FileMaker定義: ファイル - server_data.php

<?php

// IPアドレスを指定
$serverIP = '(サーバIPアドレス)';
$webCompanionPort = 80;
$dataSourceType = 'FMPro9';
$scheme = 'http';

// FileMaker ファイル情報
$databaseFileName = 'fxphp_crud_test'; // FileMaker ファイル名
$webUN = 'admin'; // ファイルを開くためのユーザ名
$webPW = 'admin'; // ファイルを開くためのパスワード

?>

新規登録画面: ファイル - fm_new.php

<?php

include_once('./fx/FX.php');
include_once('./fx/server_data.php');

// 文字列エスケープ用関数
function h($string)
{
    return htmlspecialchars(trim($string), ENT_QUOTES, 'UTF-8');
}

$data = new FX($serverIP, $webCompanionPort, $dataSourceType, $scheme);
$data->SetDBData($databaseFileName,'web_detail');
$data->SetDBUserPass($webUN,$webPW);
$dataSet = $data->FMView();
?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>FX.php データ新規登録</title>
</head>

<body>

<h1>データ新規登録</h1>

<form name="fxphp_crud_c" action="./fm_new_save.php" method="post">

    <table border="1" width="500">
        <tr>
            <th style="width:30%;">氏名</th>
            <td style="width:70%;">
                <input type="text" name="f_name" id="f_name" value="" style="width:70%;">
            </td>
        </tr>
        <tr>
            <th>年齢</th>
            <td>
                <input type="text" name="f_age" id="f_age" value="" style="width:20%; text-align:right;">
            </td>
        </tr>
        <tr>
            <th>FileMakerの<br>Webはいつから</th>
            <td>
                <select name="f_history" id="f_history">
                    <option value="">&nbsp;</option>
                    <?php 
                    foreach ($dataSet['valueLists']['valueLists_f_history'] as $key => $value)
                    {
                        ?>
                        <option value="<?php echo h($value); ?>"><?php echo h($value); ?></option>
                        <?php
                    }
                    unset($key, $value);
                    ?>
                </select>
            </td>
        </tr>
        <tr>
            <th>使用したことがある<br>バージョン</th>
            <td>
                <?php
                $i = 1;
                foreach ($dataSet['valueLists']['valueLists_f_useVersion'] as $key => $value)
                {
                    ?>
                    <input type="checkbox" name="f_useVersion[]" id="f_useVersion_<?php echo $i ?>" value="<?php echo h($value); ?>">
                    <label for="f_useVersion_<?php echo $i ?>">: <?php echo h($value); ?></label>
                    <?php
                    $i++;
               }
                unset($key, $value, $i);
                ?>
            </td>
        </tr>
        <tr>
            <th>開発に使用<br>しているOS</th>
            <td>
                <?php
                $i = 1;
                foreach ($dataSet['valueLists']['valueLists_f_useOS'] as $key => $value)
                {
                    ?>
                    <input type="radio" name="f_useOS" id="f_useOS_<?php echo $i ?>" value="<?php echo h($value); ?>">
                    <label for="f_useOS_<?php echo $i ?>">: <?php echo h($value); ?></label>
                    <?php
                    $i++;
                }
                unset($key, $value);
                ?>
            </td>
        </tr>
    </table>

    <p>
        <input type="submit" value="保存">
    </p>

</form>

</body>

</html>

新規登録処理: ファイル - fm_new_save.php

<?php

include_once('./fx/FX.php');
include_once('./fx/server_data.php');

// 文字列エスケープ用関数
function h($string)
{
    return htmlspecialchars(trim($string), ENT_QUOTES, 'UTF-8');
}

$data = new FX($serverIP, $webCompanionPort, $dataSourceType, $scheme);
$data->SetDBData($databaseFileName,'web_detail');
$data->SetDBUserPass($webUN,$webPW);
$data->SetCharacterEncoding('utf8');
$data->SetDataParamsEncoding('utf8');

$data->AddDBParam('f_name', $_POST['f_name']);
$data->AddDBParam('f_age', $_POST['f_age']);
$data->AddDBParam('f_history', $_POST['f_history']);
$data->AddDBParam('f_useVersion', implode("\r\n", $_POST['f_useVersion  ']));
$data->AddDBParam('f_useOS', $_POST['f_useOS']);

$dataSet = $data->FMNew();

if ( 0 === (int)$dataSet['errorCode'] )
{
    include_once('./fm_new_reply.php');
}
else
{
    include_once('./fm_new_error.php');
}

新規登録成功: ファイル - fm_new_reply.php

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>FX.php データ新規登録完了</title>
</head>

<body>

<h1>データ新規登録 - 完了</h1>

<p>データを登録しました。</p>

<ul>
    <li><a href="./fm_new.php">続けて登録する</a></li>
    <li><a href="./fm_list.php">一覧画面へ移動する</a></li>
</ul>


</body>

</html>

新規登録失敗: ファイル - fm_new_error.php

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>FX.php データ新規登録エラー</title>
</head>

<body>

<h1>データ新規登録 - エラー</h1>

<p>データの登録時にエラーが発生しました。<br>FileMaker Error: <?php echo h($dataSet['errorCode']); ?></p>

<ul>
    <li><a href="./fm_new.php">登録画面に戻る</a></li>
</ul>


</body>

</html>

新規登録画面を表示する前にいったんFMView()でFileMakerにアクセスし、値一覧情報を取得しているところがポイントだ。ここで値一覧情報を取得し配列としたあとで、入力画面のそれぞれ対応するフィールドに展開する。フォームに入力された情報はfmnewsave.phpに送信され、結果に応じてfm_new_reply.phpかfm_new_error.phpを表示する。なおチェックボックスといった複数の入力値が送信される場合は、nameの末尾に[]をつけPHP側で配列として受けとるようにしておく。FileMaker側に送信する際にはglueに改行文字を指定したimplodeを使用し、配列を結合した文字列をセットすればOKだ。

Webブラウザでfm_new.phpにアクセス。画面表示前に一回FileMakerにアクセスして値一覧情報を取得し、画面表示時にそれぞれforeachで値一覧情報を展開している

フォームで入力したところ

保存ボタンをクリックし、正常に処理が進んだ場合にはfm_new_reply.phpの内容が表示される

保存ボタンをクリックし、FileMaker側でエラーが発生した場合にはfm_new_error.phpの内容と、エラー番号が表示される

FileMaker側のデータベースには、フォームから送信された内容が保存されている

ページャつき一覧画面

続けて一覧画面だ。一覧画面の実装の肝は3回目の「FileMakerのCRUDはこれで完璧! - FMEdit()~FMDelete()まで」で取りあげたとおりなので、今回はさらに一歩進めて簡単なページャまで実装してみよう。

一覧画面: ファイル - fm_list.php

<?php

include_once('./fx/FX.php');
include_once('./fx/server_data.php');

// 文字列エスケープ用関数
function h($string)
{
    return htmlspecialchars(trim($string), ENT_QUOTES, 'UTF-8');
}

$data = new FX($serverIP, $webCompanionPort, $dataSourceType, $scheme);
$data->SetDBData($databaseFileName,'web_list', 5);
$data->SetDBUserPass($webUN,$webPW);
$data->SetCharacterEncoding('utf8');
$data->SetDataParamsEncoding('utf8');

$data->AddSortParam('f_serial', 'descend');
$data->FMSkipRecords($_GET['skip']);

$dataSet = $data->FMFind();

?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>FX.php データ一覧</title>
</head>

<body>

    <p>
        該当: <?php echo number_format($dataSet['foundCount']); ?>件、  
        <?php echo h(number_format($_GET['skip']+1)); ?>件目から <?php echo h($_GET['skip']+count($dataSet['data']) )?>件目を表示中
    </p>

    <table border="1">
        <thead>
            <tr>
                <th>
                    &nbsp;
                </th>
                <th>
                    シリアル
                </th>
                <th>
                    氏名
                </th>
                <th>
                    FileMakerの<br>Webはいつから
                </th>
                <th>
                    使用したことがある<br>バージョン
                </th>
            </tr>
        </thead>
        <tbody>
        <?php
        foreach ( $dataSet['data'] as $key => $value )
        {
        ?>
            <tr>
                <td align="center">
                    <del>詳細</del>
                </td>
                <td>
                    <?php
                    echo h($value['f_serial'][0]);
                    ?>
                </td>
                <td>
                    <?php
                    echo h($value['f_name'][0]);
                    ?>
                </td>
                <td>
                    <?php
                    echo h($value['f_history'][0]);
                    ?>
                </td>
                <td>
                    <?php
                    echo h(str_replace("\n", ', ', $value['f_useVersion'][0]));
                    ?>
                </td>
            </tr>
        <?php
        }
        ?>
        </tbody>
    </table>

    <p>
        <?php 
        if (!empty($dataSet['linkPrevious']))
        {
            ?>
            <a href="<?php echo h($dataSet['linkPrevious']); ?>">前のページへ</a>
            <?php
        }
        else
        {
            ?>
            前のページへ
            <?php
        }
        ?>
        / 
        <?php 
        if (!empty($dataSet['linkNext']))
        {
            ?>
            <a href="<?php echo h($dataSet['linkNext']); ?>">次のペー   ジへ</a>
            <?php
        }
        else
        {
            ?>
            次のページへ
            <?php
        }
        ?>
    </p>

</body>

</html>

レイアウト-web_list。配置するフィールドが多ければ多いほどパフォーマンスにおおきな影響が出るため、可能ならばレイアウトは別にしておこう

前回のfm_find.php内では使用しなかったFMSkipRecordsを使用するのがポイントだ。FMSkipRecordsは2回目の各種関数・メソッド紹介で触れたとおり「対象レコードが複数の場合、先頭から数えて除外したいレコード数(-skip)」を指定するものだ。FMSkipRecordsと一度に取得するレコード件数に適切な値をセットすることで、一覧画面のページャが実装できる。ページャのURIもデベロッパは自分で用意することなく、返り値の['linkPrevious']、['linkNext']を使用すればいい。これらの変数には前・次のページがある場合にのみ、自動的にskipクエリが補完されたURIが代入される。この変数を使用して簡単なページャと、何件目を表示しているかの情報を一覧画面の上下に追記している。

Webブラウザでfm_list.phpにアクセス。レコードは9件存在するが、一度に取得する数に5件と指定しているため、それ以上のレコードは取得しない。linkNextに次ページのURIが生成される

次のページへ移動したところ。skipに5が指定され、6件目から9件目のレコードが取得される

新規登録画面と一覧画面を実装した。今回作成した2つの処理はすべての画面・処理に応用できる基礎部分だ。興味がある方はこのソースファイルをベースに、詳細画面や編集画面、自分なりにFileMakerベースのWebアプリケーションを組んでみてほしい。実際に書いて動作を確認してみることこそが、習得への近道だ。次回は残りの「詳細画面」「編集画面」を作ってみよう。