FileMaker ServerにはPHPが付属しなくなって久しいのですが、現状、特にFileMaker Serverで動かなくても不便はなく、PHPの処理が欲しい場合は別途サーバを立てるのが最善策なのはいうまでもありません。しかしながら、「どうしても動かしたい」という声が後を絶たず、ここでとりあえず動かす方法をまとめておきます。そもそも、Clarisからの文書として「FileMaker ServerインストーラへのPHP添付の廃止について」があるのですが、内容が非常に込み入っていて、しかも何をしているのかわかりにくいこともあって、PHPを動かすことに躊躇している人も多いかもしれません。この文書は、FileMaker API for PHPという懐かしいライブラリを利用するための方法まで書いてありますが、今時のPHPのバージョンでこのライブラリが無事に動くとは考えづらく、その方法までは不要なのが一般的ではないかと思われます。
以下の方法が成功したのは、macOS Sequoia上のFileMaker Server 2024の場合です。これは対応OSではないのに成功したということです。また、Sequioa上ではFileMaker Server 2023でも成功しました。これも対応OSではありません(2024版はSequioa対応かどうかは公表されていないですね)。一方、macOS Ventura上のFileMaker Server 2023ではエラーになってうまくいきませんでした。これは対応OSであるのに上手くいかなかった組み合わせです。macOS内蔵のApache2に、外部からインストールするphpのモジュールという組み合わせの相性があるようなので、上手くいかない場合もあるという覚悟で進めましょう。
macOSへのFileMaker Serverのインストールはすでにインストールされているものとします。これにHomebrewをインストールします。インストール方法はサイトに記載されているので、それに応じてインストールしてください。インストール後、以下のようなコマンドを叩いて、phpをインストールします。執筆時点では、8.1以降は@をつけるので良いのですが、7.4はタップというサードパーティによるモジュール提供になっているので、コマンドの入れ方が変わります。コマンドラインでphpのバージョンを切り替えるには、unlink/linkを使います。
//最新版のPHPのインストール(執筆時点では8.3)
brew install php
//特定版のインストール
brew install php@8.1
//PHP 7.4のインストール
brew tap shivammathur/php
brew install shivammathur/php/php@7.4
//バージョンの切り替え
brew unlink php
brew link php@7.4
ちなみに、通常は最新版を使うけど、PHPのモジュールとしては古いものを使うということもアリです。以下、自分の使いたいバージョンのパスを確認してください。原則、/opt/homebrew/Cellerというディレクトリ以下にありますが、状況によって違うので、見つからない場合はいろいろ情報を探ってください。
次にコード署名を行います。コード署名とは、秘密鍵/公開鍵を使った暗号化の仕組みの応用で、ざっくり言うと「誰が作ったコードかわかる仕組み」です。iPhoneのアプリケーションでは当初より署名必須となっており、Appleが発行する証明書を利用して署名されていないと、App Storeへの登録ができなくなっています。この手法はmacOSにもかなり浸透してきており、macOSに付属しているApache2のバイナリhttpdも当初よりコード署名がなされています。
PHPはApache2用のモジュール(拡張子.so)を利用します。このモジュールは、httpdと同じプロセス空間で動きます。イメージ的にはhttpdがphpのモジュールを読み込むと思えば良いでしょう。しかし、macOSの制限により、httpdが署名されている場合は、読み込むモジュールも署名されていないといけません。homebrewで得られるモジュールは署名されていないので、そのままではモジュールとして読み込んで実行ができないのです。そこで、brewで得られたphpのモジュールに署名して、httpdが読み込んで利用できるようにする必要があります。
証明書を作る方法はいろいろあるのですが、「キーチェーンアクセス」アプリケーションを利用して、いかような手順で進めて作成される自己署名証明書で大丈夫です。ポイントは、証明書のタイプを「コード署名」にすることと、指定した名前を忘れないようにすることです。この証明書はキーチェーンに入ります。
キーチェーンにコード署名用の証明書を作ったら、コマンド入力を進めます。まず、/opt/homebrew/Celler以下にあるPHPのパスを探って、phpのモジュールを探します。バージョン等でパスの形式が違う場合がありますが、特定バージョンのphpのフォルダには.soファイルは1つだけなので、それをともかく探せば良いでしょう。そして、codesignコマンドで署名を行います。ちなみに、証明書を作ったユーザでログインしてターミナルで作業する範囲では、codesignコマンドはキーチェーンと同一のデータを使うので、コマンドにキーチェーンの場所を指定する必要はありません。コード署名をしたら、署名を読み出してみて、証明書の名前がAuthorityキーの値に見えることを確認しましょう。
モジュールを特定する(以下、「モジュールのパス」と記載)
/opt/homebrew/Cellar/php/8.3.12_1/lib/httpd/modules/libphp.so
コード署名する
codesign -f --options runtime --timestamp -s "msyk-test" モジュールのパス
//コード署名を表示する',
codesign -d -vvv モジュールのパス
//以下、表示結果Authorityの部分が、証明書の名前(作成時に指定したものとなっている)
Executable=/opt/homebrew/Cellar/php@7.4/7.4.33_6/...
Identifier=libphp7
Format=Mach-O thin (arm64)
:
Authority=msyk-test
続いて、Apache2の設定ファイルを編集します。設定ファイルは、/Library/FileMaker Server/HTTPServer/conf以下にあります。ファイルはhttpd.confなのですが、以下のように、さらに2.4という拡張子が増えているファイルがあります。これを-iをつけたlsコマンドで見ると、1列目にi-nodeが見えています。i-nodeはファイルシステムでのファイルの中身を特定する番号を思ってください。よく見ると、httpd.confとhttpd.conf.2.4は同じi-node番号です。つまり、1つのファイルの実態にファイル名が2つ割り当てられているという状況で、これらは「ハードリンク」という状態であると呼ばれます。つまり、同じ中身なのです。
% ls -l -i
total 424
158411791 drwxrwxr-x 32 fmserver fmsadmin 1024 10 9 10:19 extra
158417655 -rwxrwxr-x@ 1 fmserver fmsadmin 18175 10 8 13:32 httpd.conf
158417655 -rwxrwxr-x@ 2 fmserver fmsadmin 18144 10 8 11:57 httpd.conf.2.4
158412007 -rwxrwxr-x 2 fmserver fmsadmin 13077 1 25 2024 magic
158412007 -rwxrwxr-x 2 fmserver fmsadmin 13077 1 25 2024 magic.2.4
ここで普通にファイルを変更してもいいのですが、2.4が付いた方がバックアップと売れば、httpd.confは別ファイルとして変更したいような気がするので、たとえば次のようにコマンドを入れて、http.confとhttpd.conf.2.4を別物にしてしまうという手はあります。2つ目でhttpd.confは消えるのですが、中身は別のリンクhttpd.conf.2.4から参照できる状態なので、事実上ファイルは消えません。
cd /Library/FileMaker Server/HTTPServer/conf
rm httpd.conf
cp http.conf.2.4 httpd.conf
ということで、設定ファイル/Library/FileMaker Server/HTTPServer/conf/httpd.confを修正します。以下に、元の状態とその範囲の修正結果を示します。ページ内で、phpというキーワードを探せばすぐに元の範囲は特定できます。その前にLoadModule、そしてFileMatchディレクティブの中にSetHeaderを定義します。モジュールのパスや証明書の名前は、もちろん、前に示したものを指定します。
//元の状態',
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
//修正した状態',
LoadModule php_module モジュールのパス 証明書の名前
<FilesMatch "\.php$">
SetHandler application/x-httpd-php
</FilesMatch>
なお、ここで、LoadModuleディレクティブは、通常は証明書の名前は設定できません。Apacheのサイトでもこんな引数はありません。おそらく、macOSに搭載されているhttpdは特別にこのような設定を入れることができるようになっていると思われます。
ちなみに、Apache2のエラーログなどを見ると、正しい状態でもこのようなnoticeメッセージが出てきます。パスが違っていたり、署名されていなかったり、名前が違ったりすと別のエラーメッセージになり、Apache自体が起動しません。
[Tue Oct 08 12:44:50.253541 2024] [so:notice] [pid 17129] AH06662: Allowing module loading process to continue for module at /opt/homebrew/opt/php/lib/httpd/modules/libphp.so because module signature matches authority "Developer ID Application: Nii Masayuki (W3WVRUYJRT)" specified in LoadModule directive
ということで、お決まりの、phpinfo()関数の結果は以下のとおりです。Darwin OS内で動いているのが見えます。もう、HomebrewのPHPは、Sequoia対応になっていますが、この時はSonoma対応の段階でしたけど、ちゃんと動いていました。
そういうわけで、FMDataAPIについても動作確認しました。一連の作業は、自分の普段使いのMacで確認したので、HomebrewによるPHPはいろんなものが最初から入っているため一発で動きましたが(というか、その環境でFMDataAPIを開発している)、足りないモジュールがあればbrew install モジュール名 等でインストールしましょう。
一連の作業で面白い動作を発見しました。codesignコマンドなのですが、SSH経由でログインをしてコード署名を行うと、adhocという名前が出てくる、おそらくはちゃんとしてない署名になります。Authorityは設定されないので、ApacheのPHPモジュールに署名しても稼働はしません。つまり、codesignコマンドは、macOSにログインをして、その上でターミナルから起動して署名しないといけないのです。セキュリティ的な理由なのか、あるいはキーチェーンの扱いなんかがあるのかもしれませんが、ともかく、ログイン方法でコマンドの動作が違って場合によっては正く署名されないというのは落とし穴かもしれません。プロバイダにあるMacや、鍵のかかったサーバルームにあるMacなんかの場合はよく注意をしましょう。
そういうわけで、HomebrewがインストールしたPHPのモジュール、macOSに内蔵されているApache2のhttpdを使うということで、コード署名が必要になるということだったのですが、ちなみに、Homebrewのアップデート(brew update/brew upgradeコマンド)を行うと、場合によってはバイナリが置き換わります。上記のような手順の場合、PHP 8.3の新しいマイナーバージョンの登場で古いものは消されるので、つまりはアップデートがあればその都度コード署名をしなければならないという、面倒かつ、実運用では危険な状態でもある点に注意を払う必要があります。
ちなみに、FileMaker Serverは入れておきたいけど、PHPでも開発作業等をしたい場合、つまり、それぞれ別々に利用するのが一般的な場合は、ここにあるような作業をしなくても、phpを-Sオプションをつけて、サーバモードで動かすのが普通です。公開ディレクトリをカレントディレクトリにして、php -S localhost:9000などとコマンドを入れて、ブラウザから「http://localhost:9000」に接続します。ということで、やっぱりFileMaker ServerのApache2上でPHPを動かす必要性って限られるんですよね。