PHPによるデータベース・アクセス

 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の代表格である、 PostgreSQLMySQL のデータベースに接続して、検索(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などで規定されている通り、 英大文字、小文字の区別がないのが「常識」なので、 違和感がある方もおられるかもしれません(私も戸惑いましたー)。

Open Source Web Architecture Top

(first uploaded 2001/12/24 last updated 2004/07/26, URANO398)

Gポイントポイ活 Amazon Yahoo 楽天

無料ホームページ 楽天モバイル[UNLIMITが今なら1円] 海外格安航空券 海外旅行保険が無料!