PHP は、動的な Web サイトの開発に最もよく使用されているプログラミング言語の 1 つで、非常に強力で効率的であるだけでなく、極めて単純でもあります。PHP はその柔軟性から、初心者に非常に適した言語となるはずです。
PHP は言語そのものとしては優れていますが (これは、XHTML と組み合わせた場合は尚更のことです)、PHP
アプリケーションの大半には、使い勝手の良いデータ保管手段が必要となります。通常、その必要を満たすのは、MySQL や PostgreSQL
などのデータベースです。この場合、PHP がデータ保管システムに接続するためには、mysql_query() や
pg_query() などの関数が使えるコネクターを使用する必要があります。大抵は、そのようなコネクターを使用しても問題ありませんが、ビジネス要件によっては、データをスプレッドシートのようなものに保管して、個人が簡単に操作できるようにしなければならないことがあります。そういった場合には、データにアクセスするためには別の種類のコネクターが必要になります。
例えば、SQL を送信する対象として特定のデータベース・システムにとらわれることもなく、また構成を行ったどのデータ・ストアに対してもその SQL
を実行できるようにしたいとしたらどうでしょう。これがまさに、ODBC (Open Database Connectivity)
が作成された理由です。適切なコネクターがインストールされていれば、ODBC によって Microsoft Excel や CSV をはじめとするさまざまなデータ・ファイル・タイプにアクセスすることができます。ODBC は、PHP 開発を「データベース・コネクターにとらわれない」ようにするコネクターであり、odbc_query() などの関数を、MySQL、PostgreSQL、SQLite、Microsoft SQL Server、IBM DB2、Sybase、OpenLink Virtuoso、FileMaker、そして Microsoft Office Access などのデータベースすべてに対して使用します。さらに、ODBC ドライバーを適切にセットアップすれば、CSV と Excel スプレッドシートにも ODBC を使用することができます。
ODBC は、プログラミング言語とデータ・ストアをつなげるためのソフトウェア・ドライバー・システムです。1992年に登場したこの無料のオープンソース・システムは、プログラミング言語およびデータベース・クエリー・アクセス全体で関数や構成などの接続方式を標準化することを目指しています (SQL 標準)。
ODBC の動作は、二重のインターフェース (あるいはコネクター構造) の役割を果たしています。1 つは ODBC システムに対するプログラミング言語システムとしての役割、もう 1 つはデータ・ストレージ・システムに対する ODBC システムとしての役割です。したがって、ODBC にはプログラミング言語と ODBC との間のドライバー (PHP-ODBC ライブラリーなど) と、ODBC とデータ・ストレージ・システムとの間のドライバー (MySQL-ODBC ライブラリーなど) が必要となります。ODBC システムそのものに加え、これらのドライバーがデータ・ソースの構成を処理し、データ・ソースとプログラミング言語の曖昧性を許容します。
PHP は一般的に、動的 Web サイトを駆動するためのサーバー・サイドの言語として使われているプログラミング言語です。動的で弱い型付けの言語であることから、PHP には柔軟性があります。多くの開発者にとって PHP が妙に馴染み深いのは、この言語が C プログラミング言語の影響を受けているためです。PHP は、1995年に無料のオープンソース・プログラミング言語として登場しました。コネクターを介して PHP でデータベースを操作することで、XHTML および HTML を生成して Web ブラウザーにレンダリングすることができます。
SQLは、データ・ストアに問い合わせをするためのクロスプラットフォームの言語です。SQL は主にリレーショナル・データベースに使用されていますが、プロシージャー用の拡張や、オブジェクト指向用の拡張、そしてオブジェクト・リレーショナル用の拡張もあります。最近では、MySQL、PostgreSQL、SQLite、DB2 (商用エディションと Express-C エディションの両方)、Microsoft SQL Server、OpenLink Virtuoso、FileMaker、および Microsoft Access に SQL が実装されています。接続システム (ODBC) を使用すれば、このすべてに、PHP のようなプログラミング言語で接続することができます。
ここからは、標準的な LAMP (Linux-Apache-PHP-MySQL) 環境をこの柔軟な LAPO (Linux-Apache-PHP-ODBC) 環境に変身させる例を検討します。Linux 上で動作する ODBC ドライバーの選択肢としては、一般に iODBC と unixODBC があります。いずれのドライバー・セットにもそれぞれ長所と短所があります。両方とも PHP で使用できますが、対象とするデータベースは異なります。2 つのうち、私が優先して使用しているのは iODBC です。その理由は、従来から PHP や Ruby などの Web プログラミング言語と強いつながりがあること、そして ODBC と相性の良い MySQL や OpenLink Virtuoso のようなデータベースとの動作に安定性があることです。けれども、これは好みの問題に過ぎないので、皆さんそれぞれの効率性の要件を調べることをお勧めします。内部の微妙な違いを別とすれば、iODBC と unixODBC はプログラミング言語で使用する際には同一の方法で動作します (PHP 関数はまったく同じです)。また、データベースとの接続に関しても然りです (例えば、MySQL は iODBC を使用するか、unixODBC を使用するかによって影響を受けることはありません)。
iODBC と unixODBC はどちらも Linux のパッケージ・マネージャーに用意されています。例えば、Debian、Ubuntu、または Linux Mint
コマンドラインでは、sudo apt-get install iodbc を実行するとインストールすることができます。
データベース・システムがまだインストールされていない場合には、この時点でインストールしてください (MySQL または PostgreSQL など)。その上で、ODBC とデータベースを接続するコネクターをインストールします。このコネクターはデータベースによってさまざまに異なりますが、MySQL の場合を例に取ると、コネクターをインストールするには、MySQL Web サイトからオペレーティング・システムに対応するドライバーをインストールします。
apt をサポートする Linux ディストリビューションの場合には、コンソールからコマンド sudo apt-get install libmyodbc を実行してインストールすることができます。
データベースをインストールした後は ODBC クライアントを構成することで、そのデータベースを操作できるようにする必要があります。それには、iodbcadm-gtk などのプログラムを実行するか、手動で iODBC ファイルを編集します (Linux の場合、このファイルは /etc/iodbc.ini にあることが多いです)。
次に、PHP ODBC ドライバーをインストールする必要があります。それには、iODBC または unixODBC を PHP コンパイル・スクリプトに追加するという方法と
(非常に複雑な方法です)、PHP-ODBC ライブラリーをインストールするという方法があります。apt ベースのディストリビューションでは、コマンド sudo apt-get install php5-odbc を使用することができます。
対話モードで PHP を実行して (php -a)、接続フローをテストします。このコマンドを実行すると PHP 対話コンソールが開くので、リスト 1 の例に示すような方法で対話することができます。
リスト 1. コマンドラインでの ODBC 接続
php > $conn = odbc_connect(
"DRIVER={MySQL ODBC 3.51 Driver};Server=localhost;Database=phpodbcdb",
"username", "password");
php > $sql = "SELECT 1 as test";
php > $rs = odbc_exec($conn,$sql);
php > odbc_fetch_row($rs);
php > echo "\nTest\n—--\n” . odbc_result($rs,"test") . “\n";
Test
----
1
php > odbc_close($conn);
php > exit;
|
リスト 1 のコードを以下で分析してみましょう。
- PHP の
odbc_connect()関数を使用して接続を確立します。この関数が引数として取るのは、ODBC 接続文字列、ユーザー名、パスワードです。接続文字列は odbc.ini ファイルと突き合わせられるので、あらかじめこの文字列が一致することを確認しておいてください。 - 変数を、SQL 文を表す文字列にインスタンス化します。
odbc_exec関数を使用して SQL を実行します。この関数は接続および SQL 文の文字列を引数として取り、結果セットを返します。- 結果セットから 1 つの行だけを取り込むために、結果セットをパラメーターとして取る
odbc_fetch_row()を使用します。これはイテレーター関数です。つまり、この関数を再度呼び出すと、結果セットの中の次の結果が返されます (結果セット内に結果がなくなるまで、関数を呼び出すごとに次の結果が返されます。結果がなくなると、関数は false を返します)。 - 結果セットと列名 (文字列) を引数として取り、行イテレーターが指す行に含まれるセルの値を返す
odbc_result()関数を使用します。 - 接続自体を引数として取る
odbc_close関数を使用して、ODBC 接続を閉じます。 exitコマンドを送信して PHP 対話モードを終了します。
上記は見事なフローですが、Web アプリケーションの規模ではそれほど役に立ちません。このコードをクライアント・サーバー・スタイルの Web ブラウジング・モードでテストするには、Apache や Lighttpd などの Web サーバーがインストールされている必要があります (Linux を実行している場合は必ず、お使いの Web サービスに対応する PHP モジュールを入手してください。そうでないと、PHP を実行できません)。
上記と同じ手法を、今度は Web サーバーを使用して実行する場合をリスト 2 に記載します。PHP コードの内容はリスト 1 で入力した内容と似ていますが、リスト 2 では結果をコマンドラインに出力するのではなく、XHTML 形式でエクスポートしています。
リスト 2. XHTML ベースの ODBC 接続の例
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>PHP and ODBC: XHTML Example 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<?php
$conn = odbc_connect(
"DRIVER={MySQL ODBC 3.51 Driver};Server=localhost;Database=phpodbcdb",
"username", "password");
if (!($conn)) {
echo "<p>Connection to DB via ODBC failed: ";
echo odbc_errormsg ($conn );
echo "</p>\n";
}
$sql = "SELECT 1 as test";
$rs = odbc_exec($conn,$sql);
echo "<table><tr>";
echo "<th>Test</th></tr>";
while (odbc_fetch_row($rs))
{
$result = odbc_result($rs,"test");
echo "<tr><td>$result</td></tr>";
}
odbc_close($conn);
echo "</table>";
?>
</body>
</html>
|
また、このリストには、リスト 1 にはなかった内容が追加されています。それは、odbc_fetch_row() を while ループの中に入れて、このイテレーター関数を最大限活用していることです。これにより、SQL がテーブルに対して複数の結果を要求するような、やや複雑なものになった場合には、レンダリングされる XHTML テーブルに新しい行が作成されるようになります。
XHTML とHTML にはさまざまなタイプがあり、ブラウザーによるサポートの程度も使いやすさも異なります。リスト 2 が生成する標準化された XHTML 1.0 Strict は、データを中心とした強力なクロスブラウザー文書を開発するのに最適な XHTML の形式の 1 つです。
ODBC 関数には大きく分けて 4 つのタイプがあり、それぞれが接続、クエリーの実行、データの取得、そしてエラーのレポートを目的とした関数です。クエリーを実行する関数は、データの作成、読み取り、更新、削除 (別名、CRUD 操作) を行う標準的なデータベース・トランザクションに対処することができます。
開始されたプロセスにはすべて終わりがなければなりません。そうでなければ、メモリーとプロセッサーに問題が生じることになってしまいます。したがって、データベース接続についても必ず終了させる必要があります。
すでに説明したように、odbc_connect() は ODBC 対応の接続文字列、データベースのユーザー名とそれに関連するパスワードを引数として取ります。この関数が返す接続オブジェクトは、PHP プログラム全体を通して使用することができます。以下のコードに、一例を示します。
$connection = odbc_connect($connection_string, $username, $password); |
また、以前のサンプル・コードに示されていたように、odbc_close() は接続オブジェクトを引数に取って、ODBC
とデータベースとの通信を終了します。必ず接続を終了しなければならないという点はいくら強調しても強調し足りないほどです。接続を終了しなければ、データベースとの接続数が多くなり過ぎて、最終的にはデータベース管理システムを再起動するはめになります。さらに悪いことに、コンピューター全体を再起動しなければならない場合も考えられます。それを防ぐのが、odbc_close($connection); です。
前のサンプル・コードでも使用した odbc_exec() は、接続オブジェクトと SQL 文の文字列を引数に取って、その
SQL
文を実行し、結果セット・オブジェクトを返します。結果セット・オブジェクトは、通常はデータベース管理システムのメモリー内にあり、そのオブジェクトを操作する関数でしか解読できないことから、かなり厄介な代物です。odbc_exec() 行は、$resultset =
odbc_exec($connection, $sql); のような形になります。
不明な変数を SQL に注入するのに驚くほど役に立つのは、odbc_prepare() 関数と odbc_execute 関数の組み合わせです。odbc_prepare()
関数がデータベース管理システムで SQL 文を準備した後、そこに odbc_execute()
関数が変数を注入します。単純に PHP で SQL 文を連結して組み立てて、それを odbc_exec() で送信するよりも、このほうが強力で、セキュリティーにも効率性にも優れた方法となります。この 2 つの関数を組み合わせると、以下のようになります。
$resultset = odbc_prepare($connection, $sql); $success = odbc_execute($resultset, $variables); |
リスト 3 は、ユーザーのテーブルで場所と誕生日の変数を基準に人を検索するために作成した典型例です。SQL 文の文字列に含まれる疑問符 (?) に注目してください。これは、odbc_execute() 関数の 1 次元配列に定義された変数を表します。
リスト 3. odbc_prepare および odbc_execute コマンドによる SQL 変数の注入
$location = "London";
$mindateofbirth = time() - 567648000; /* i.e. 18 years ago from now */
$resultset = odbc_prepare(
$connection,
"SELECT * FROM user WHERE location = ? AND dateofbirth <= ?"
);
$success = odbc_execute($resultset, array($location, $mindateofbirth));
|
odbc_fetch_row()
はクエリーを実行した結果セットを引数に取り、イテレーターのポインターを次の行にシフトします。この関数は、さまざまなセルを取得するために odbc_result() 関数と組み合わせて使用されることがよくあります。
odbc_fetch_row($resultset); |
これまでに記載したサンプル・コードでは、odbc_result() は以下のように $resultset と列名の文字列を引数に取り、セルの値を返しています。この関数と odbc_fetch_row() 関数を組み合わせて使用することで、結果セット内の特定の行を指すことができます。
$value = odbc_result($resultset,"columnname"); |
クエリーの結果セットからデータを取得するために使用するイテレーター関数であるという点では、odbc_fetch_array() 関数も同様です。ただし、この関数の場合には、列名をキーとし、セルを値とした行を表す配列を返します。
$rowarray = odbc_fetch_array($resultset); |
odbc_fetch_array() と同様の odbc_fetch_object() は、配列の代わりに行を表すオブジェクト指向の構造を取得します。この関数は列名をオブジェクトのプロパティーとし、セルの値をプロパティーの値とします。
$rowobject = odbc_fetch_object($resultset); |
以下に示す関数は、一連の結果を HTML に出力するのに役立ちます。これは結果の単純なレンダリングですが、プロトタイピングやデバッグの際に重宝するはずです。
odbc_result_all($resultset); |
odbc_num_fields() はなかなか有用な関数で、この関数は単に結果セットを引数に取って、その結果セットに含まれる行の数を返してくれます。
$numberofrows = odbc_num_rows($resultset); |
2 つの重宝なPHP ODBC 関数として挙げられるのは、エラーが発生した場合にはエラー・コードを返し、エラーが発生していない場合には false を返す odbc_error()、そしてユーザー・フレンドリーなメッセージを返す odbc_errormsg() です。この 2 つの関数を組み合わせて、単純なエラー・メッセージング・シーケンスを形作ることができます。
if (odbc_error()) {
echo "I've found a problem: " . odbc_errormsg($conn);
}
|
開発中にエラーが発生した場合のもう 1 つのヒントとして、問題の原因となっている行の近くにプリント文を追加することを決して恐れないでください。ただし、他の人々に見せるときにはもちろん、これらの「デバッグ行」を削除することが前提となります。以下の PHP 関数を覚えておいてください。この関数が救いの手となることは珍しくありません。
print_r($variable); |
この単純な関数は任意の変数を引数に取って、それを画面に表示します。変数は、整数や文字列などの単純なものにすることも、多次元配列やオブジェクトなどの複雑なものにすることもできます。
どこにでも (例えば、Drupal や WordPress、Joomla など) デプロイできる Web
アプリケーションを構築するとします。このようなアプリケーションは大抵の場合、1 つのデータベース (例えば、MySQL) とそのデータベースに固有の関数
(例えば、mysql_connect()) を使用して構築し、それから別のデータベース
(例えば、PostgreSQL) と連動するように関数を (例えば、pg_connect() に) 変更するという方法で慎重に作成し直されるものです。ODBC を使用する場合、これは無駄な作業となります。構成は完全にアプリケーションの初期化に含まれていて、ODBC 関数はデータベース・システムに依存しないためです。
ただし、注意しなければならない点として、すべてのデータベース管理システムが標準化された SQL を共有するとは言え、データベース管理システムにはそれぞれに固有の拡張機能が含まれている場合もあります。このことが理由で、既存の PHP-MySQL、PHP-PostgreSQL、あるいは PHP-MS-SQL アプリケーションを PHP-ODBC アプリケーションに変換するのは多少厄介です。したがって、一からアプリケーションを構築する際には、標準化された SQL だけを使用するように注意しなければなりません (あるいは、少なくとも極めて一般的な SQL の拡張機能だけを使用してください)。
前述のとおり、ODBC を使用してスプレッドシートに接続することは可能です。データベースの場合と同じく、それにはコネクターを使用しなければなりません。使用できるコネクターは多数あります。その一部はオープンソースですが、大半は独自仕様のコネクターです。その一例として、Windows の Microsoft Office には Excel スプレッドシート用の ODBC コネクターが付属しています。ODBC を介してスプレッドシートを扱うのはかなり厄介な作業になることもありますが、単純なスプレッドシートをデータベース・テーブルに変換すれば、多くの面倒な作業が省かれるはずです。その一方、スプレッドシートの ODBC 接続が確立された後は、その接続をほぼデータベース接続と同じように扱うことができます。つまり、同じ ODBC PHP 関数を SQL のような言語で使いながら、Excel の標準スプレッドシートの式を扱うことができるというわけです。
Linked Data およびセマンティック Web との関連
Linked Data movement (Linked Data 運動) で焦点としているのは、Web 全体でデータを結び付けることです。こうすることによるメリットは数多くあります。その多くはデータの特定の要素を理解するマシンにもたらされますが、例えばユーザーにとっても情報を見つけやすくなるなどのメリットがあります。Linked Data movement で使用している標準は、セマンティック Web にすでに存在する標準 (Resource Description Framework や Web Ontology Language など) およびインターネット/Web 標準 (HTTP や OpenID など) です。URI が接続文字列にいくらか似ているという点で Linked Data の接続手法は ODBC と似ていること、そしてセマンティック Web の問い合わせ言語 (SPARQL) は確立された接続を介する SQL のようなものであることが理解され始めてきています。
Linked Data が ODBC に多少似ているという理論を拡大解釈すれば、Linked Data ストア (「Triple Store」など) に対して ODBC で接続を確立して、SPARQL クエリーを ODBC 接続に送信することも可能なはずです。その事例となっているのは OpenLink Virtuoso で、標準 ODBC 接続を介して接続できるようになっています。
iODBC は、GPL (GNU General Public License) と Berkeley Software Development オープソース・ライセンスの両方の下で使用が許諾されます。UnixODBC も同じく GPL オープンソース・ライセンスが適用されます。これは、この 2 つのライブラリーを使用して何を開発しようとも、オープンソースにする必要はなく、プロプライエタリー・ソフトウェアにすることができることを意味します。Microsoft の ODBC ドライバーもプロプライエタリー・ソフトウェアの一部にすることができますが、Microsoft Office ソフトウェア (Access データベースおよび Excel スプレッドシートの場合) および SQL Server (SQL Server データベースの場合) のライセンス契約には拘束されます。
ODBC は、普遍的な接続性を最大限に引き出すための素晴らしい手法です。ODBC は効率性を向上させ、Web ベースの Linked Data などといった新しい形のデータを扱えるようにアプリケーションを拡張することを可能にします。ただし、ODBC には欠点もあります。普遍的な接続性を実現するためには、SQL クエリーをどのように作成するかを慎重に選ばなければなりません。使用可能なすべての SQL コマンドのうち、データベース管理システムで共通して使用できるのは一部のコマンドに限られるためです。この記事が、PHP プログラミング言語を使用して ODBC でデータベースを操作するために必要な情報を提供できたことを願います。
学ぶために
- SQL チュートリアルの「W3Schools」セクションは、SQL の初心者向きチュートリアルおよび上級者向けの参照ポイントとして役立ちます。このセクションでは、標準化された内容と、データベース管理システムに依存した機能内容について詳しく説明しています。
- PHP
チュートリアルの「W3Schools」セクションも、PHP を使い始めようとしている開発者、そしてこの言語の参照ポイントを必要とする PHP 開発者に役立つリソースとなります。
- PHP.net は、PHP のあらゆる情報の発信源です。
- PHP.net のマニュアルに、すべての PHP ODBC 関数に関する詳細が説明されています。
- Linked Data、公開データのリンク、およびセマンティック Web に関する詳細を調べるには、LinkedData.org が最適なポータルです。また、W3C Semantic Web ポータルも有用なリソースになります。
- SQL
標準は、International Organization for Standardization が管理しています。
- オープンソース技術を使用して開発し、IBM
の製品と併用するときに役立つ広範囲のハウツー情報、ツール、およびプロジェクト・アップデートについては、Open source ゾーンを参照してください。
- developerWorks
の Technical events and webcasts: 最新技術についての情報を入手してください。
- Technology
bookstore: この記事で紹介した技術やその他の技術に関する本を参照してください。
- developerWorks
podcasts: ソフトウェア開発者向けの興味深いインタビューとディスカッションを聞いてください。
製品や技術を入手するために
- iODBC.org では、iODBC のインストールおよびセットアップに関して豊富な情報を提供しているだけでなく、汎用 ODBC およびさまざまなデータベース・システムとプログラミング言語へのコネクターについても役立つ情報を提供しています。
- unixODBC.org では、unixODBC のインストール、セットアップ、およびコネクター・ドライバーに関する情報を提供しています。
- MySQL.org は、2010年から Oracle ファミリーに加わった MySQL Database Management System に関する開発者向けの情報源です。
- MySQL ODBC Connector は MySQL から直接入手できます。
- MSDN で Microsoft
ODBC ドライバーの詳細および ODBC Data Source Administrator プログラムのヘルプ・ファイルを参照してください。この 2 つのロケーションで、ODBC による Access、SQL Server、および Excel の操作についての詳細を調べられます。
- PostgreSQL.org は、PostgreSQL データベース管理システムのホームです。
- PostgreSQL ODBC Connector プロジェクトは、無料のオープンソ-ス・ソフトウェアとして利用できます。
- OpenLink Virtuoso は「汎用サーバー」として、Web ホスト (PHP 言語を含む)、データベース、ODBC 接続性、およびセマンティック Web 技術を提供します。OpenLink Software は、オープンソース iODBC ライブラリーの主な保守管理者でもあります。このライブラリーは、オープンソース・バージョンおよび独占仕様バージョンで用意されています。
- OpenLink Virtuoso 以外の Web
サーバーとしては、Apache HTTP Server およびLighttpd Server を調べてください。
議論するために
- developerWorks blogs: developerWorks blogs から
developerWorks コミュニティーに加わってください。
