サンプルソリューションのデータは、新しいサンプルデータを作る を参照してください。
この記事で使用するソースコードは、FileMaker Data API を使う 2025年版 vol.12#残りの HTML ソースコードの PHP 化 にまとめてあります。
その後の変更(Find Records のテストと JSON ファイル)は、FileMaker Data API を使う 2025年版 vol.13 を参照してください。
現在の構造は以下の通りです。
.
├── css
│ ├── bootstrap-common.css
│ └── fmda-form.css
├── find-records-test.php ※ vol.13 で追加
├── find-records-test2.php ※ vol.13 で追加
├── html
│ └── edit-record.html
├── index.php
├── js
│ ├── fmda-form-check.js
│ └── fmda-select-page.js
├── json
│ ├── html-contents.json
│ ├── standings-al-east-2024.json ※ vol.13 で追加
│ └── standings-all-2024.json ※ vol.13 で追加
└── php
├── bs-builder-class.php
├── bs-frame-class.php
├── filemaker-data-api-class.php
├── php-functions.php
└── preferences.php
利用環境
以下の環境を前提に説明しています。
- Claris FileMaker Pro 21.1.1.41 macOS
- Claris FileMaker Server 21.1.1.40 Ubuntu 22(AMD)
- サーバ: Ubuntu 22.04.5 LTS
- SSL 証明書
- リクエストする側のサーバ(任意)
開発段階では、以下を使用した方が楽でしょう。
Web ページの作成は、以下を条件とします。
- Bootstrap v5.3.3
- Bootstrap Examples Checkout を土台にしています。
- PHP 8.2.22
割り切った global キーワードの使用
global キーワードは、グローバルスコープの変数をローカルスコープで操作するためのキーワードで、無闇に使用すると、プログラムのメンテナンス性に問題が出ることもあります。
しかし、開発段階では、割り切って、一定のルールの元に使用すると、プログラムの構造が把握しやすくなります。
ここで採用するルールは、以下のものです。
- 原則、ブロック単位で仮に関数化する
- 仮の関数は、別ファイルに置く
- 仮の関数で、必要なグローバルスコープの変数を global キーワードで設定する
- 仮の関数は引数を与えない
- 仮の関数は戻り値を返さない
- 引数、戻り値が必要になったら、正規の関数として、別ファイルに移す
- 正規の関数は、原則、global キーワードを持たない
といってもイメージが全然、湧かないと思いますので、上記、ルールで書き換えた find-records-test3.php
を示します。
前回の find-records-test2.php は、HTML 出力部分を除いて、今回やろうとしていることと同じですので、比較してみてください。
find-records-test3.php
<?php
require_once(__DIR__ . '/php/bs-frame-class.php');
require_once(__DIR__ . '/php/bs-builder-class.php');
require_once(__DIR__ . '/php/php-functions.php');
require_once(__DIR__ . '/php/filemaker-data-api-class.php');
@$page_indentity = $_POST['page-identity'];
$page_indentity = $page_indentity === null ? 1 : $page_indentity;
require_once(__DIR__ . '/php/preferences.php');
require_once(__DIR__ . '/php/temporary-functions.php');
authorization_data();
$fmda = new FileMakerDataApi($host, $version);
auth_login();
auth_validate_session();
$request_body_json_file = __DIR__ . '/json/standings-all-2024.json';
$request_body = json_get_element_raw($request_body_json_file);
records_find_records();
auth_log_out();
大変、短くなって、処理の流れが想像しやすくなったのではないでしょうか。
同様に、index.php
も書き換えます。
index.php 新版
<?php
require_once(__DIR__ . '/php/bs-frame-class.php');
require_once(__DIR__ . '/php/bs-builder-class.php');
require_once(__DIR__ . '/php/php-functions.php');
require_once(__DIR__ . '/php/filemaker-data-api-class.php');
@$page_indentity = $_POST['page-identity'];
$page_indentity = $page_indentity === null ? 1 : $page_indentity;
require_once(__DIR__ . '/php/preferences.php');
require_once(__DIR__ . '/php/temporary-functions.php');
authorization_data();
$fmda = new FileMakerDataApi($host, $version);
if (!isset($result)) {
// 最初のアクセス
auth_login();
auth_validate_session();
$request_body_json_file = __DIR__ . '/json/standings-all-2024.json';
$request_body = json_get_element_raw($request_body_json_file);
records_find_records();
auth_log_out();
}
BsFrame::HtmlBegin($color_modes_js, $description, $author, $title, $bootstrap_css, $bs_css_integrity, $bs_frame_css, $custom_css);
BsFrame::LoadColorModesSvg();
BsFrame::ColorModes();
BsBuilder::MainBegin($logo_svg, $logo_svg_width, $page_heading[$page_indentity], $page_lead[$page_indentity]);
BsBuilder::InfoItem($info_heading, $info_number_of_items, $info_item_heading, $info_item_content);
BsBuilder::GetInfo();
BsBuilder::CreateForm($form_preferences, $form_controls);
BsBuilder::CreatePagination($page_indentity);
BsBuilder::MainEnd();
BsBuilder::CreateFooter($copyright_year, $copyright_holder, $link_items);
BsFrame::HtmlEnd($bootstrap_js, $bs_js_integrity, $custom_js);
要するに、ソースコードの流れを把握しやすくするために、処理を隠しているだけのことです。
隠した処理は、temporary-functions.php
に移っています。
temporary-functions.php
<?php
function authorization_data( ): void
{
global $host, $version;
global $database, $username, $password;
global $layout, $bearer_session_token;
// FileMaker Server 情報
$host = '(FileMaker Server ドメイン名)';
$version = 'vLatest';
// FileMaker ソリューション情報
$database = '(FileMaker ソリューション名)';
$username = '(FileMaker ユーザ名)';
$password = '(パスワード)';
// リクエスト情報
$layout = 'standings';
$bearer_session_token = null;
}
function auth_login( ): void
{
global $fmda, $response, $bearer_session_token, $database, $username, $password;
// ログイン
$response = $fmda->login($database, $username, $password);
// ログイン成功?
if ($fmda->getMessagesCode($response) === '0') {
// ログイン成功なら、Bearer Session Token を取得する
$bearer_session_token = $fmda->getBearerSessionToken($response);
} else {
// ログイン失敗の処理を書く
echo "<div class=\"alert alert-danger\" role=\"alert\">FileMaker Data API へのログインに失敗しました。</div>\n";
}
}
function auth_validate_session( ): void
{
global $fmda, $response, $bearer_session_token;
// セッションの検証
$response = $fmda->validateSession($bearer_session_token);
}
function records_find_records( ): void
{
global $fmda, $response, $bearer_session_token, $database, $layout, $request_body;
global $result, $data_info, $team_data;
global $info_item_content;
if ($fmda->getMessagesCode($response) === '0') {
// セッション有効なら、行いたいリクエスト実行
// レコードの検索
$response = $fmda->findRecords($database, $layout, $bearer_session_token, $request_body);
// 結果セット処理
$result = $fmda->json2array($response);
if ($fmda->getMessagesCode($response) === '0') {
$data_info = $result['response']['dataInfo'];
$team_data = $result['response']['data'];
}
} else {
// セッション無効なら、必要な Web データを保持して、ユーザに再ログインを促す
echo "<div class=\"alert alert-warning\" role=\"alert\">セッションが切れました。再ログインしてください。</div>\n";
}
}
function auth_log_out( ): void
{
global $fmda, $response, $bearer_session_token, $database;
// ログアウト
$response = $fmda->logOut($database, $bearer_session_token);
}
この作業をしていないと、temporary-functions.php
とほぼ同じ長さだけ index.php
が長くなってしまうということです。
正規の関数に格上げした段階で、temporary-functions.php
が短くなっていくわけですが、理想は、temporary-functions.php
なくなってしまうことです。
dataInfo ブロック
前回の find-records-test2.php
のデータ表示をしたいわけですが、まず、Find Records で取得したデータをここで元々使われている $info_item_content
配列の中身を、仮データから正規のものに変更する必要があります。
この処理は、temporary-functions.php
の records_find_records()
関数に追加します。
records_find_records() 関数
function records_find_records( ): void
{
global $fmda, $response, $bearer_session_token, $database, $layout, $request_body;
global $result, $data_info, $team_data;
global $info_item_content;
if ($fmda->getMessagesCode($response) === '0') {
// セッション有効なら、行いたいリクエスト実行
// レコードの検索
$response = $fmda->findRecords($database, $layout, $bearer_session_token, $request_body);
// 結果セット処理
$result = $fmda->json2array($response);
if ($fmda->getMessagesCode($response) === '0') {
$data_info = $result['response']['dataInfo'];
$team_data = $result['response']['data'];
// 追加部分
array_push($info_item_content, $data_info['database']);
array_push($info_item_content, $data_info['layout']);
array_push($info_item_content, $data_info['table']);
array_push($info_item_content, $team_data[0]['recordId']);
array_push($info_item_content, $team_data[0]['modId']);
array_push($info_item_content, $data_info['totalRecordCount']);
array_push($info_item_content, $data_info['foundCount']);
array_push($info_item_content, $data_info['returnedCount']);
}
} else {
// セッション無効なら、必要な Web データを保持して、ユーザに再ログインを促す
echo "<div class=\"alert alert-warning\" role=\"alert\">セッションが切れました。再ログインしてください。</div>\n";
}
}
現時点での状態は、最初のレコードを表示する前提で、他のことは考慮していませんので、$team_data[]
配列のインデックスは 0 になっています。
この変更に伴い、preferences.php
にも変更点があります。
preferences.php 変更部分(46行目から)
$info_item_heading = [];
$info_item_content = [];
foreach ($temp_array['infoItems'] as $key => $value) {
array_push($info_item_heading, $value['heading']);
}
foreach の中にあった array_push($info_item_content, $value['content']);
を削除しているだけです。
この変更に伴い dateInfo の見出しとラベルも変更が必要になります。❻ については後回しにします。
テキストコンテントは、html-contents.json
に入っていますので、該当部分を変更します。
"contents" JSON オブジェクトの "infoHeading"
"infoHeading" : "FileMaker 情報",
"infoItems" JSON 配列
"infoItems" : [
{
"heading" : "ソリューション"
},
{
"heading" : "レイアウト"
},
{
"heading" : "テーブル"
},
{
"heading" : "レコード ID"
},
{
"heading" : "修正 ID"
},
{
"heading" : "テーブルのレコード数"
},
{
"heading" : "現在のレコード数"
},
{
"heading" : "取得したレコード数"
}
],
これで、dataInfo ブロック 改め、FileMkaer 情報ブロックに表示したい情報が表示されるようになりました。
今回、手をつけていない部分
- FileMaker 情報ブロックの❻
これは、単純に削除する予定です。
- 機能判別
今回は、ファーストアクセスしか考慮していません。
フッタのリンクをクリックした際の処理は、フォームデータ表示が出来てから、追加する予定です。
- フォームデータ表示
Find Records で、$team_data
配列には、既に、フォームに表示したい情報が入っています。
これについては、次回、追加したいと思います。