接続文字列とiniファイル | [連載]PHPでデータベース(PDO) 第2回

接続文字列とiniファイル IT技術
接続文字列とiniファイル

このシリーズはPHPでデータベースを扱いたいと考えている方を対象とした記事となっています。

前回はデータベースを扱うプログラムの中で、PDOというものがどういった役割をするもので、PDOを選択することのメリットなどを紹介しましたが、今回からはいよいよデータベースをプログラムから扱う実際の処理について解説を開始していきます。

PDOを使ってデータベースへ接続する際に指定することになる、ユーザー名やパスワードといったセキュリティ上重要な情報を、プログラム外部に保存して利用する方法も合わせて紹介しています。

コンストラクタでデータベースへの接続

PDOでデータベースへの接続をするのはとても簡単で、PDOクラスのインスタンスを生成する際のパラメータで必要な情報を受け渡すだけという形になっています。厳密にいうと、PDOクラスのコンストラクタ(__construct)にて処理されます。以下は公式マニュアルに載っているサンプルコードです。

参考 : PHP : PDO::__construnct – Manual

$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';

$dbh = new PDO($dsn, $user, $password);

最後の行のnewによって、PDOクラスのインスタンスを生成しています。指定している引数(パラメータ)については次項で解説しています。

接続の終了はPDOオブジェクトが破棄されたタイミングなので、スコープ外に抜ければ自動的に破棄されますが、nullなどを代入して明示的に破棄しても構いません。

各パラメータなどについて、次項以降で詳しく見ていきましょう。

接続文字列: DSN (Data Source Name)について

コンストラクタ最初のパラメータは、DSN(Data Source Name)と呼ばれ、データベースへの接続文字列とも呼ばれることがあります。一般的にこの部分では、データベースの種類やデータベースのホスト(IPアドレス等)と共に接続先のデータベース名を指定します。紹介した例はMySQLに対しての接続文字列なので、他のデータベースを利用する場合は適宜書き換える必要があります。(例 : PostgreSQLの場合はpgsqlなど)

参考 : PHP: PDO ドライバ – Manual

MySQLに接続する際のDSN文字列については、上記URLから辿っていくことができますが、少しわかりにくいかもしれないので、直接マニュアルのページのリンクも置いておきますので、ご利用ください。

参考 : PHP: PDO_MYSQL DSN – Manual

MySQLのDSNには、以下6種類のパラメータを指定することができるようになっています。

DSN 接頭辞MySQLの場合はmysql:になります。
host接続先のホスト名(又はIPアドレス)を指定します。
port接続先のポート番号を指定します。
dbname接続するデータベース名を指定します。
unix_sockethost/portの代わりに、MySQLのUnix Socketを指定します。
charsetデータベース接続に利用する文字セット(utf8など)を利用します。
(ポートや文字セットを含めた指定例)
$dsn = 'mysql:host=localhost;port=3307;dbname=testdb;charset=utf8';

dbnameに指定するデータベース名は、接続先のデータベース上にあらかじめ作成しておかなければなりません。ここでは詳しく紹介しませんが、利用するデータベース(MySQLなど)のCreate DatabaseといったSQLを参考にしてみてください。既存のデータベースへ接続する場合は、管理者からデータベース名を受け取っておく必要があります。

ユーザー名/パスワードをハードコーディングすべきでない理由

コンストラクタ(__construct)の第二/第三引数はユーザー名とパスワードになっています。これはデータベースサーバーへの接続に使用するユーザー情報になるので、あらかじめ利用するデータベース側で準備しておく必要があります。既存のデータベースへ接続する場合は、管理者からユーザー名パスワードを受け取る必要があります。

上記サンプルは、プログラムコード内にユーザー名とパスワードが含まれてしまっています。プログラムの中に情報を埋め込むことを「ハードコーディング」と呼びます。

一般的にハードコーディングの最大の弱点は「可用性の低下」です。接続先のデータベースの状態やネットワークの設定が変わっただけで、プログラムの修正作業が発生してしまうというソフトウェアは、非常に扱いにくく、様々な場面で困ることになります。開発用のサーバーと本番用のサーバーが異なることは多い他、開発途中に使用するデータベースの種類が変更になることもあります。そういった場合に、プログラム内に記述があればプログラマーの作業になってしまいますが、設定ファイルなど外部に切り出しておけば、プログラマーがいなくても変更が可能となります。本番データベースのアクセス権を開発委託先へ渡せない場合には、そもそもユーザー名パスワードをプログラマーが受け取れません。

また、PHPプログラムはWebサーバー経由で外部からのアクセスを受け付けるファイルでもあり、そこに直接セキュリティーに関する情報が記載されていることは、コンプライアンス上問題とされることも多いため、対策方法を知っておくことは重要です。

iniファイルを活用してハードコーディング問題を回避

PHPのマニュアルでも紹介されている方法ですが、iniファイル(一般的な諸設定を記述しておくファイル)を利用することで問題を容易に回避することができるので、簡単に紹介します。ここではiniファイルでの解決方法を紹介しますが、もっと厳重に管理したい場合などは、暗号化ファイルを活用するなど適宜変更して実装しても構いません。

以下はPHPのマニュアルに紹介されているコードを、更に簡略化したものになっています。

// PHP
// iniファイルの読み込み
$_SETTINGS = parse_ini_file('./settings.ini', true);

// PDOによる接続 (iniファイルの情報を利用)
$db = new PDO(
  "mysql:hostname={$_SETTINGS['db']['host']};dbname={$_SETTINGS['db']['name']}",
  $_SETTINGS['db']['user'],
  $_SETTINGS['db']['pass']);

以下は上記プログラムで読込するsetting.iniファイルの例です。

[db]
host = localhost
name = dbname
user = dbuser
pass = dbpassword

プログラムとしては、parse_ini_fileでiniファイルを読み込み/解析(parse)して、結果を連想配列$_SETTINGSに保持しています。後は文字列の連結でDSNの生成と、ユーザー名・パスワードを同連想配列から指定しているという形です。文字コードなどを指定したい場合は、iniファイルへ項目を追加して対応が可能になるなど、とても柔軟なコーディングと運用が可能となります。

まとめ

PDOを利用すると、データベースの接続はとても簡単に行うことができます。ただ、前回説明した通り抽象化レイヤーであるPDOでは細かな接続の管理ができないなど弱点もあります。利用するデータベースエンジンが持つ最大限の能力を利用する必要がある場合は、各データベースベンダーが提供する接続方法を利用しましょう。PDOは汎用的なデータベースに関する処理を、単純なプログラムで実現可能な点が最大のメリットです。

次回からはいよいよデータベースの操作について紹介していきます。