1
2

More than 3 years have passed since last update.

【PHP】PDO接続周り

Last updated at Posted at 2021-06-24

Laravelなどのフレームワークでは、クエリビルダやEloquentを使って簡単にDBから値を取ってくることができます。
今回は、PDOを使ってDB接続し、データを取ってくる流れを記載していきます。

  1. DBに接続(例外処理も含めて)
  2. SQL文の準備
  3. 準備したSQL文に値をバインドする
  4. 準備したSQLを実行する
  5. 実行結果を配列などで取得する

この順番で解説していきます。

1. DBに接続(例外処理も含めて)

$pdo = new PDO($dsn, $username, $password, $driver_options);

のような形で、DB接続するためのPDOインスタンスを作成します。

try {
  $dbh = new PDO(
    'mysql:host=サーバー名;dbname=データベース名;charset=utf8', // $dsn
    'ユーザー名', // $username
    'パスワード', // $password
    array( // $driver_options
      PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // DB接続でエラーが発生したときに、PDOExceptionの例外を捕捉する
      PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 実行結果を配列で返すオプション
      PDO::ATTR_EMULATE_PREPARES => false, // 静的プレースホルダーを使うように設定
    )
  );
} catch (PDOException $e) {
  $error = $e->getMessage();
}
  • new PDO で、DBに接続するためのPDOインスタンスを作成します。
  • $driver_optionsの部分は、PDOで使用するoptionを指定します。 基本的には配列で指定します。 PDO::ATTR_EMULATE_PREPARESの部分は後々解説します。

2.SQL文の準備

$sql = 'SELECT * FROM article WHERE id = ?';
$prepare = $dbh->prepare($sql);
  • $sqlには、SQL文を書きます。 ?の部分はプレースホルダーになっていて、後々そこに値を割り当てます。 このような仕組みをプリペアドステートメントというらしいです。
    • ?のプレースホルダーを使用する時は、静的プレースホルダー
    • :カラム名のプレースホルダーを使用する時は動的プレースホルダーと言います。
    • 動的プレースホルダーの方が処理速度が早いらしいですが、SQLインジェクション対策のため、基本的には静的プレースホルダーを使用することが推奨されます。

【PHP超入門】クラス~例外処理~PDOの基礎 - Qiita

3. 準備したSQL文に値をバインド(割り当て)する

bindValue(パラメータID,バインドする値,データ型

という形でバインドします。

$prepare->bindValue(1, (int)$id, PDO::PARAM_INT);

整数型の引数を割り当てるには、(int)という形で型キャストをする必要があります。
【PHP入門講座】 型変換 - Qiita

整数以外は、デフォルトでPDO::PARAM_STRが指定されます。

静的プレースホルダーの場合、パラメータIDの部分には1から始まる値を入れます。
例えば、

$sql = 'SELECT * FROM article WHERE id = ? and title = ?';

のように、?のプレースホルダーが2つある場合は、

$prepare->bindValue(1, $id, PDO::PARAM_INT);
$prepare->bindValue(2, $title, PDO::PARAM_STR);

のように、第一引数が1,2...と数字が続いていきます。

4. 準備したSQLを実行する

$sql = 'SELECT * FROM article WHERE id = ?';
$id = 1;
$prepare = $dbh->prepare($sql);
$prepare->bindValue(1, (int)$id, PDO::PARAM_INT);
$prepare->execute();

execute()メソッドでSQLを実行します。

5. 実行結果を配列などで取得する

$result = $prepare->fetchAll(PDO::FETCH_ASSOC);

fetchAllメソッドで、条件に合致した全てのデータを配列として返します。

全体像

<?php
function dbConnect()
{
  try {
    $dsn = 'mysql:host=' . 'db' . '; dbname=' . 'test_php' . ';charset=utf8;';
    $driver_options = [
      PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
      PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
      PDO::ATTR_EMULATE_PREPARES => false,
    ];
    $dbh = new PDO($dsn, 'root', 'test', $driver_options);
  } catch (PDOException $e) {
    print('ERROR:' . $e->getMessage());
    exit;
  }
  return $dbh;
}

function getData()
{
  $dbh = dbConnect();
  $sql = 'SELECT * FROM article WHERE id = ?';
  $prepare = $dbh->prepare($sql);
  $id = 1;
  $prepare->bindValue(1, (int)$id, PDO::PARAM_INT);
  $prepare->execute();
  $result = $prepare->fetchAll(PDO::FETCH_ASSOC);
  return $result;
}

$result = getData(); // $result をHTML側で表示する場合は、HTML側でループして表示させます。
?>
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2