|
PHPでWebアプリケーションを開発することのCGIに優越する重要な点のひとつは、
豊富なデータベース・アクセス関数群が組み込みで用意されていることでしょう。
実際、Oracle、SybaseとMS SQL Server、ODBC、Mysql、PostgreSQLなどなど、
商用・無償を問わず、有力なRDBMSソフトウェアの多くにPHPは対応しています。
惜しいことに、PHPの各RDBMSへのアクセス関数群はそれぞれ別個に開発されてきた経緯があり、
関数名や引数の順番などに微妙に差違があります。
これはPHPコミュニティでも早くから指摘されてきた問題で、
解決策として現在では、標準ライブラリPEARに「データベース抽象化レイヤー」
としてDBライブラリが搭載されています。
(より新しいMDBなどの代替ライブラリもあります)
DBを使うと、DSN(JavaのJDBCでいうURLみたいなもの)を切り替えるだけで、
同じ関数を使っていろいろなRDBMSにアクセスできるのでとても便利です。
そのため現在ではRDBMS固有のAPIを使うより、
DBやMDBを使う方がお勧めなのですが、
ここでは過去の遺産ということで固有APIを使った例をまず載せていきます。
このページには、オープンソースRDBMSの代表格である、
PostgreSQL
と
MySQL
のデータベースに接続して、検索(SELECT)処理を行うサンプルを載せてみました。
<html><head>
<meta http-equiv="Content-type" content="text/html;charset=euc-jp">
<title>PostgreSQLへのアクセス</title></head>
<body bgcolor="white">
<h1>PostgreSQLデータベースを検索するサンプル</h1>
<?
function putError($msg){
print "<h2>おおっと</h2>";
print $msg ."<br>";
}
function searchDB($targetWord){
/* データベースに接続します。*/
if(($con = pg_connect("localhost", 5432, "", "", "udb")) == 0){
putError("データベースに接続できません。");
return;
}
/* SQLを実行します。*/
$k = "%${targetWord}%";
$sql = <<<SQL
SELECT ITEM_CLASS, ITEM_CODE, NAME
FROM ITEMS
WHERE NAME LIKE '$k'
SQL;
if(! ($rset = pg_exec($con, $sql))){
putError("実行に失敗しました:" . pg_errormessage($con));
}
/* 結果を取り出します。 */
$nrows = pg_numrows($rset);
$ncols = pg_numfields($rset);
print "${nrows}件のデータが見つかりました。<br>\n";
print <<<HEADER
<table border="1">
<tr bgcolor="#c0c0ff">
<th>品目クラス</th><th>品目コード</th><th>品名</th></tr>
HEADER;
for($i=0; $i<$nrows; $i++){
print "<tr>";
for($c=0; $c < $ncols; $c++){
print "<td>" . pg_result($rset, $i, $c) . "</td>";
}
print "</tr>";
}
print "</table>";
/* 結果集合を開放します。 */
pg_freeresult($rset);
/* データベース接続を終了します。 */
pg_close($con);
}
if(isset($HTTP_POST_VARS["target_word"])){
searchDB(trim($HTTP_POST_VARS["target_word"]));
}
else{
?>
<form action="pgsql1.php" method="post">
検索したい文字列:
<input type="text" name="target_word"><br>
<input type="submit" value="検索">
</form>
<?
}
?>
</body></html>
|
まずPostgreSQLに接続しようとする場合の例ですが、
PHPからPostgreSQLへ接続する場合、
接続時にPostgreSQLユーザー名とパスワードを渡して認証する方法と、
認証を行わない方法があります。認証を行わない場合は、
Apache(httpd)プロセスのUIDでPostgreSQLに接続することになります。
httpdのユーザーは通常nobodyですから、
この方法を使う場合はPostgreSQLの管理者アカウントになり、
nobodyというユーザーをPostgreSQLに登録しておきます。
% su pgmaster
$ createuser nobody
検索する表のSELECT権限を付与しておくのも忘れずに。
今度はMySQLの例です。機能はPostgreSQLの場合と同じで、
書き方もほとんど同じにしてあります。
一見して気づくのは、pg_なにがしという関数とmysql_なにがしという関数では、
対応する名前が微妙に違ったり、引数の順番が逆になっていたりすることです。
この辺り、気づきにくいミスを生む温床になる可能性が高いので、
どちらのRDBMSを使う場合にも気をつけなくてはいけませんね。
<html><head>
<meta http-equiv="Content-type" content="text/html;charset=Shift_JIS">
<title>支店テーブル検索 MySQL版</title></head>
<body bgcolor="white">
<h1>支店テーブルを検索するサンプル(MySQL版)</h1>
<?php
function putError($msg){
$url = $_SERVER[REQUEST_URI];
print <<<MSG
<h2>おおっと</h2>
$msg<br>
<a href="$url">検索条件入力に戻る</a><br>
</body></html>
MSG;
exit(0);
}
if(isset($_POST["shiten_name"])){
if(empty($_POST["shiten_name"])){
putError("検索する支店名を入力して下さい。");
}
/* データベースに接続します。*/
if(($con = mysql_connect("localhost", "urano", "urano398")) == 0){
putError("データベースに接続できません:" . mysql_error());
}
mysql_select_db("udb", $con);
/* SQLを実行します。*/
/* MySQLでは、表の名前の大文字、小文字は区別されるので、
* 正確に指定する必要があります。
*/
$k = $_POST["shiten_name"] . "%";
$sql = <<<SQL
SELECT SHITEN_CODE, SHITEN_NAME, EMPLOYEE_NUM
FROM SHITEN
WHERE SHITEN_NAME LIKE '$k'
SQL;
if(! ($rset = mysql_query($sql, $con))){
putError("実行に失敗しました:" . mysql_error());
return;
}
/* 結果を取り出します。 */
$nrows = mysql_num_rows($rset);
$ncols = mysql_num_fields($rset);
print "${nrows}件のデータが見つかりました。<br>\n";
print <<<HEADER
<table border="1">
<tr bgcolor="#ffc0c0">
<th>支店コード</th><th>支店名称</th><th>従業員数</th></tr>
HEADER;
while($a = mysql_fetch_row($rset)){
print "<tr>";
for($c=0; $c < $ncols; $c++){
print "<td>" . $a[$c] . "</td>";
}
print "</tr>";
}
print "</table>";
/* 結果集合を開放します。 */
mysql_freeresult($rset);
/* データベース接続を終了します。 */
mysql_close($con);
}
else{
?>
<form action="<?= $_SERVER[REQUEST_URI] ?>" method="POST">
支店名:
<input type="text" name="shiten_name"><br>
<input type="submit" value="検索">
</form>
<?php
}
?>
</body></html>
|
MySQLでは、ユーザはユーザIDとクライアントのホストアドレスのセットで一意に識別されます。
PHPからローカルで動くMySQLデータベースに接続しようとするときのユーザは
「@localhost」がついたものになります。
したがって、この場合ではユーザ「urano」ではなく「urano@localhost」
に、このDBや表を検索できる権限を与えておかなければいけません。
grant select on udb.items to urano@localhost
identified by 'urano398';
またUNIX系OS上でのMySQLでは、
データベースや表の名前の大文字、
小文字は区別される点にとりわけ注意が必要です。
一般にRDBMSの世界では、標準仕様SQL92などで規定されている通り、
英大文字、小文字の区別がないのが「常識」なので、
違和感がある方もおられるかもしれません(私も戸惑いましたー)。
(first uploaded 2001/12/24 last updated 2004/07/26, URANO398)
|