業務アプリ開発講座

設定phpの作成 | すべてのプログラムの設定情報を管理

Init.phpを作っていきましょう。ファイル名のInitはInitialization(初期化)の略です。様々なプログラミング言語でiniファイルというテキストファイルを使って各種設定情報を管理することがあります。それを踏襲しています。iniファイル以外にもconfigファイルという呼び方をすることも多いです。例えば、apacheはhttpd.confというファイルで各種設定情報を管理しています。

本アプリを作り進むにつれてまだまだ、設定情報や機能を書き加えますが、今回書き加えるソースは下記の通りです。

date_default_timezone_set('Asia/Tokyo');
ini_set('display_errors', DisplayError::DISPLAY);

$GLOBALS["name"]	= $name = [];
$GLOBALS["path"]	= $path = [];

$name['app']		= 'Bookmin 管理';
$name['server']		= filter_input(INPUT_SERVER, 'SERVER_NAME');
$path["root"]		= str_replace('/manager', '', filter_input(INPUT_SERVER, 'DOCUMENT_ROOT'));
$path["sitemap"]	= $path["root"].'/app-data/sitemap.json';
$path["validation"]	= $path["root"].'/app-data/validation.json';
$path["tempHtml"]	= $path["root"].'/includes/temp-html';

class DisplayError{
    const NONE    = 0;
    const DISPLAY = 1;
}
class JsonDecodeType{
    const TYPE_OBJECT = false;
    const TYPE_ARRAY  = true;
}

順番に解説して行きます。

date_default_timezone_set('Asia/Tokyo');

日付時刻関数で使用されるタイムゾーンを東京に設定しています。試しに引数にアメリカのロサンジェルスAmerica/Los_Angelesを設定して、画面に日時を表示してみましょう。

echo date('Y-m-d H:i:s');

としてみると、東京と表示される時間が違いますね。
タイムゾーンの設定はphp.ini内のdate.timezoneでも設定できます。ですので、php.iniでタイプゾーンが東京に設定されている場合は、ここで設定する必要はありません。もし、環境によってphp.iniの編集権限がない場合や未設定などの時のために、ここでも再設定できることを覚えておくと便利です。

ini_set('display_errors', DisplayError::DISPLAY);

これはプログラムの実行中にエラーが発生した場合、その詳細情報を画面に出力するかを設定しています。開発中はエラー情報は即座に知りたいものですし、逆に本番稼動中は見せたくありません(ログは出力しますが)。そこで、この一箇所でシステム全体のエラー表示を制御します。そうすれば表示・非表示の切り替えが簡単に設定できます。

is_set()の第2引数DisplayError::DISPLAYは、ソースの下の方でclassとして宣言しています。ここでプログラミングで重要な注意点があります。is_set()の第2引数は[0, 1]のどちらかを指定するわけですが、直接数字を渡すような書き方は絶対に避けましょう。条件式で比較する値もそうですが、数字ですとそれが何を意味するものなのかが、設計書やマニュアルを見ないとわからなくなってしまいます。プログラミングではソースコードを見ただけで意味がわかるようなコーディングをしなければなりません。開発をしているまさにその時はその数字が意味するところを覚えていますので、問題ないかもしれませんが、半年、1年後に改めてソースを見た時、その数字が何を意味しているかは、まず覚えていないでしょう。ましてや新しいプログラマーが初めてそのソースを見た時、すぐに理解することは不可能です。そのようなソースは、保守性の悪いプログラムということになります。そこで、数字やフラグ、区分に名前をつけてあげることで人が見た時にグッと理解しやすくなります。

ここではclass化して定数を設定していますが、定数だけを設定しても構いません。is_set()の前に同じ階層に

const DISPLAY_ERROR_NONE = 0;
const DISPLAY_ERROR_DISPLAY = 1;

と宣言し、

ini_set('display_errors', DISPLAY_ERROR_DISPLAY);

としても良いでしょう。ただ、そうすると定数の宣言をその定数を使用するコードより前に記述する必要があります。定数を参照しようとした段階で、未設定ということになるからです。

class化する利点は、is_set()などの関数の前に記述する必要がないということと、「何の何」と、定数の意味合いをグルーピングと言いますか、カテゴリー化できるとことにあります。

JavaやC#などオブジェクト指向系の言語ではEnum(列挙体)という型が備わっています。通常、オブジェクト指向系の言語ではEnum型を使用して、数字に置き換えられるような設定情報を書きます。しかし、PHPには列挙体という機能そなわっていませんので、classと定数を使用して表現します。

続いて、グローバル変数の設定です。

$GLOBALS["name"]	= $name = [];
$GLOBALS["path"]	= $path = [];

「変数のスコープ」の章で出てきました$GLOBALS変数です。ここでは2つのグローバル変数を宣言します。宣言の仕方が今までしょちょっと違いますね。

複数の変数に同じ値を代入する場合、このように=で連結して、一括して代入することができます。言語によってこのような書き方ができるものとできないものがありますので、気をつけましょう。そして、このような宣言をした場合、変数$nameの値を変更すると$GLOBALS["name"]の値も変更されます。ソースを簡潔に書きたい場合のちょっとしたテクニックです。

中身にを見ていきましょう。

$name['app']	= 'Bookmin 管理';
$name['server']	= filter_input(INPUT_SERVER, 'SERVER_NAME');

アプリの名称と、サーバー名を設定します。値を取得する場合は、それぞれ$GLOBALS["name"]["app"],
$GLOBALS["name"]["server"]と記述します。連想配列ですね。

ちなみにサーバー名には、VirtualHostで設定した、www-dev.bookmin.jpが入ります。このサーバー名はHTML headタグ内のbaseタグの値として使用します。このようにサーバー名を動的に取得できるようにしておくと、環境が変わってもの設定情報を手動で変更する必要がなくなります。開発環境で開発してソースコードをそのまま本番環境に移行してもちゃんと動くわけです。

続いてパス情報グローバル変数です。

$path["root"]	= str_replace('/manager', '', filter_input(INPUT_SERVER, 'DOCUMENT_ROOT'));
$path["sitemap"]	= $path["root"].'/app-data/sitemap.json';
$path["validation"]	= $path["root"].'/app-data/validation.json';
$path["tempHtml"]	= $path["root"].'/includes/temp-html';

まず、rootパスとして、bookminディレクトリまでの絶対パスを取得します。サーバー環境変数のDOCUMENTO_ROOTはVirtualHostで設定したC:\wwwroot\bookmin\managerを返します。bookminディレクトリは一つ上の階層になりますので、DOCUMENTO_ROOTから/managerを削除し、bookminのルートディレクトとします。

続いて、sitemap.jsonvalidation.jsonファイルへのパスを設定します。
最後の$path["tempHtml"]に設定したディレクトリは今後、様々なHTMLのテンプレートタグを格納するclassファイルを置く場所になります。

次回はAppData.phpを作成します。