PDOを使ったPHPでのデータベース基本操作


PHPでデータベースを操作する方法をまとめました。簡易な解説なので、プログラムの日が浅い人は理解できないかもしれません。復習用としてお使いください。

PHPでデータベースを操作する場合は、まずPDOオブジェクトを生成します。この時はコンストラクタでデータベース情報を設定しておきます。 後は、そのPDOオブジェクトのメソッドでデータベースを操作するだけです。今回は、$dbhという変数でPDOオブジェクトを管理しています。

データベース接続に必要な情報

まずはサンプルコードです。

<?php
define('DB_HOST', 'DBの場所');
define('DB_NAME', 'DBの名前');
define('DB_USER', 'ユーザー名');
define('DB_PASSWORD', 'パスワード');

// 文字化け対策
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND=>"SET CHARACTER SET 'utf8'");

// PHPのエラーを表示するように設定
error_reporting(E_ALL & ~E_NOTICE);

// データベースの接続
try {
     $dbh = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASSWORD, $options);
     $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
     echo $e->getMessage();
     exit;
}

// ここからデータベースを操作します
?>

最初に接続に使うDB情報を定数で用意。変数でもOK

define('DB_HOST', 'DBの場所');
define('DB_NAME', 'DBの名前');
define('DB_USER', 'DBのユーザー名');
define('DB_PASSWORD', 'パスワード');

PHPBookを見たところ1,2行目はDSNとしてまとめていました。

$dsn = 'mysql:dbname=uriage;host=localhost'

つまり、以下のように書き換えれます。こちらの方が覚えやすいと思うので、これからこちらの表記を使いたいと思います。

define('DB_DSN', 'mysql:dbname=DB_名前;host=DB_の場所');
define('DB_USER', 'ユーザー名');
define('DB_PASSWORD', 'パスワード');

文字化け対策

今回はXAMPPを利用しているのですが、データベースのセルに日本語が含まれていると文字化けが発生しました。

原因が全然わからないのですが、PDOコンストラクタ、つまりPDOオブジェクトを作成するときに、次の引数を入れればいいみたいです。

$options = array(PDO::MYSQL_ATTR_INIT_COMMAND=>"SET CHARACTER SET 'utf8'")

以下のサイトでは5つの実験が記述してあり考察に参考になると思います。

PDOでMySQL接続したら文字化けした時のメモ

エラーを確認する

PHPはエラーを表示しないのが標準設定らしいので、自分で設定を変更しなければいけません。そこで次の一文でPHPのエラーを表示させます。

error_reporting(E_ALL & ~E_NOTICE)

また、データベースのエラー表示は次のように別途記述します。

dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)

これはPDOの設定PDO::ATTR_ERRMODEにPDO::ERRMODE_EXCEPTIOを設定しています。

詳しいくことはPHPマニュアルに載っています。

  • PDO::ATTR_ERRMODE: エラーレポート
  • PDO::ERRMODE_EXCEPTION: 例外 を投げる

引用元:phpマニュアル - PDO::setAttribute

基本の4つのSQL文

SQL文は次の3種類に分かれます。

  1. DDL(Data Definition Language - データ定義言語)
    • CREATE
    • DROP
    • ALTER
  2. DML(Data Manipulation Language - テータ操作言語)
    • SELECT
    • INSERT
    • UPDATE
    • DELETE
  3. DCL(Data Contorol Language - データ制御言語)
    • COMMIT
    • ROLLBACK
    • REVOKE

とりあえず、データベースの操作をしたいのなら2番目のDMLを覚えておけばいいと思います。これが一番使うので。

次のテーブルを使ってサンプルを記しておきます。

テーブル名:Shohin_table
商品ID 商品 価格 メーカー 発売日
0001 ゲーム機 18,000 XXクリエイティブ 2012-06-14
0002 包丁 5.600 一刀入魂 2011-04-11
0003 コンロ 3,400 かかじん 2011-04-11

1追加

2013年4月1日発売の2,800円のゲームソフトと、

2013年5月20日発売の5,000円の高級和菓子を追加したい。

2更新

ゲーム機の発売日が2ヶ月延期したのでデータを更新したい。

それとお詫びとして値段を500円引く事になった。

3削除

商品のコンロが発売中止になったので、削除したい。

4閲覧

上司に次のようにデータベースを表示するように言われた。

  1. 発売日の古い順にする。
  2. 同じ発売日の場合は、値段の安い順にする。
  3. 商品IDとメーカーは表示させなくてよい

この4つの操作は次のようなSQL文を書きます。

-- 1追加
INSERT INTO Shohin_table VALUES ('ゲームソフト', '2800', '2013-04-01'),
                               ('高級和菓子', '5000', '2013-05-20');
-- 2更新
UPDATE Shohin
     SET '発売日' = '2012-08-14',
          '価格'    = '17,500' 
  WHERE '商品ID' = '0001';

-- 3削除
DELETE FROM Shohin_table
 WHERE '商品ID' = '0003';

-- 4閲覧
SELECT '商品', '価格', '発売日'
  FROM Shohin_table

注意点としては、WHEREでどのレコード(行)が対象かを決めないと、全部のレコードに対して実行されます。1つのレコードに対して操作するならIDを条件としておくといいでしょう。(IDが被らない場合)

PDOでSQL文を実行する

SQL文を実行する方法は2種類

※本来カラム名は日本語は使用できません。今回はわかりやすいように日本語で表記していますが、このままだとエラーが出ると思います。SQL文、データベースのカラム名は英数字で記述して下さい。

query

$dbh->query(ここにSQL文を書く);

// SQL文とその中のパラメータを変数にすることもできる
$sql = 'SELECT  '商品', '価格' WHERE '商品ID' = $shohin_id';
$dbh->query($sql);

SQL文を即時実行、1回しか使わないならqueryメソッドを使うといいです。パラメータに変数を使うことで、より柔軟にすることもできますが、実はSQLを使いまわす用のメソッドもあります。それがprepareメソッドです。使い方は2通りあります。

prepare

// パターン1:変数を?で代用する
$dbh->prepare("UPDATE Shohin
                    SET '価格' = ? 
                    WHERE id = ?");

// パターン2:変数名の$をコロンに変える
$dbh->prepare("UPDATE Shohin
                    SET '価格' = :kakaku 
                    WHERE id = :id");

このように?(クエスチョンマーク)と:(コロン)でどの部分を後で置き換えるかを決めておきます。prepareはSQL文の準備をするメソッドで、実行するにはexcuteメソッドを使います。

$stmt = $dbh->prepare('SQL文');

// ?を置き換える場合
$stmt->execute(array(500, 2));
// :(コロン)を置き換える場合
$stmt->execute(array(':kakaku'=>500, ':id'=>2));

executeメソッドを実行したことで、queryメソッドを実行したことと同じになります。また、ここでstmという変数がでてきましたが、ここにはexcuteの戻り値が入っています。query,prepare,excuteはともにPDOStatementオブジェクトというものが返されます。このオブジェクトはデータベースから引っ張ってきた情報をPHPで出力、つまりサイトの画面に表示したり、計算に使うために必要です。

データを出力する

queryやexcuteメソッドでSQL文を実行しただけでは、その結果が戻り値として返されるだけで、値としてはまだ使えません。そこでfetchメソッドを使います。

商品 価格
ゲーム機 18,000
包丁 5.600
コンロ 3,400

fetch

fetchメソッドは引数にデータの取り出し方のオプションを決めるのですが、これはprepareで?か:(コロン)と似たようなものです。それでは例を見てましょう。

データはSELECT文で以下のようなデータを引っ張ってきたとします。それをstmに入れています。

// $stmtには既にSQL文を実行した結果が入っているとする
// パターン1
$result = $stmt->fetch(PDO::FETCH_NUM));
print($result[0]);
print($result[1]);

// パターン2
$result = $stmt->fetch(PDO::FETCH_ASSOC);
print($result['id']);
print($result['name']);

この場合の結果はどちらもーム機1800と表示されます。

fetchメソッドは1行ずつ結果を取り出すので、全部を取り出す場合にはどちらかのパターンをループで回します。

while($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
    print($result['id']);
    print($result['name']);
}

このようにすることで、$stmtの中のレコード(行)が1行ずつ取り出されて表示されていき、いずれ$stmtの中のレコードが空となり、ループは終了します。

まとめ

PHPでデータベースを操作するにはPDOオブジェクトを使って、SQL文の実行、データの管理、取り出しを行います。これを図で俯瞰してみると次のようになります。

さらに復習したい方はこちらの記事がおすすめです。ざっくりとまとまっていて見やすいです。

はじめてPDOを使う人が知っておきたい 6 + 1 のポイント