PDOの基本

PDOとは

PDO(PHP Data Object) は、PHP 5.1.0以降で利用できるデータベースを操作できるクラスライブラリです。複数のRDBMS(MySQL、PostgreSQL、SQLiteなど)に対応したAPIを提供しているため、同じプログラムでも複数のデータベースに対応できます。

CRUDに対応したAPI

PDOにはCRUD処理するためのメソッドやオブジェクトが用意されており、一貫性のあるプログラムができます。

フレームワークでも採用され高速

PDOは比較的高速に動作し、Laravel などのPHPフレームワークなどでも採用されています。特別な理由がなければ PDOの利用をお勧めします。

PDO詳細マニュアル

PHP Data Objects

データベース接続設定

設定ファイルの作成

env.php を作成し、DBの種類、データベース名、ホスト名などを設定します。

env.php
<?php
const DB_CONNECTION = DB接続方式;
const DB_HOST = ホスト名;
const DB_PORT = ポート番号;
const DB_USERNAME = ユーザ名;
const DB_PASSWORD = パスワード;
const DB_DATABASE = データベース名;

PDO接続用設定一覧

項目名 内容例 説明
DB接続方式 'mysql' PDOで使用するデータベースドライバ名
ホスト名 'localhost' または '127.0.0.1' 自分のPCで動かす場合のホスト設定
ポート番号 '3306' MySQLのデフォルトポート番号
ユーザ名 'root' データベースに接続するユーザー名
パスワード 設定による MySQL Rootパスワード

パスワード

パスワードはMySQLをインストールした方法によって違います。

種類 パスワード
通常インストール MySQLインストール時に設定
XAMPP(Windows) ''
MAMP(Mac) root
Homebrew(Mac) ''

本番運用の注意

rootユーザでの操作は本番公開するときはとても危険です。 別途ユーザ、パスワードをつけるようにしましょう。今回は開発環境で簡易的に説明するために、デフォルトパスワードで進めていきます。

データベース名

Webアプリで利用するデータベース名を指定します。

const DB_DATABASE = 'php_sns';

PDOの利用方法

PDOオブジェクト

DSN情報ユーザ名パスワードを指定し、PDO接続します。戻り値は PDOオブジェクト が返されます。

$pdo = new PDO(DSN, ユーザ名, パスワード, オプション);

DSN

DSN(Data Source Name) は、PDOでデータベースに接続するプロトコルです。MySQLの場合、mysql: ではじめて各パラメータを記述します。

mysql:dbname=データベース名;host=ホスト;port=ポート番号;charset=utf8mb4;

文字コード

文字コードは文字化け対策として UTF-8 Unicode で設定します。

charset=utf8mb4;

DB接続

DB設定「env.php」を読み込んで、「connect_test.php」でPDO接続してみましょう。

ファイル構成

basic
├── env.php
└── connect_test.php

データベース作成

MySQLクライアントツールを利用して「php_sns」データベースを作成します。

DB接続設定

DB設定ファイル作成

「env.php」にDB設定を定数定義します。

<?php
const DB_CONNECTION = 'mysql';
const DB_HOST = 'localhost';
const DB_PORT = '3306';
const DB_USERNAME = 'root';
const DB_PASSWORD = '';
const DB_DATABASE = 'php_sns';
  • ホスト、ユーザー名、パスワード、データベース名などは各環境にあわせます
  • 設定ファイルを作成しておくと、環境が変わったときに変更しやすくなります。

DB設定読み込み

DB設定ファイルを読み込み変数に代入します。

connect_test.php
<?php
// 設定ファイル読み込み
require_once 'env.php';

// 変数設定
$db_connection = DB_CONNECTION;
$db_name = DB_DATABASE;
$db_host = DB_HOST;
$db_port = DB_HOST;
$db_user = DB_USERNAME;
$db_password = DB_PASSWORD;

DSN設定

DSNの設定を変数 $dsn で定義します。

<?php
require_once 'env.php';

$db_connection = DB_CONNECTION;
$db_name = DB_DATABASE;
$db_host = DB_HOST;
$db_port = DB_HOST;
$db_user = DB_USERNAME;
$db_password = DB_PASSWORD;

// DSN設定
$dsn = "{$db_connection}:dbname={$db_name};host={$db_host};port={$db_port};charset=utf8;";

PDO接続

try & catch構文で例外処理(Exception)に対応した、PDO接続処理をします。

connect_test.php
<?php
require_once 'env.php';

$db_connection = DB_CONNECTION;
$db_name = DB_DATABASE;
$db_host = DB_HOST;
$db_port = DB_HOST;
$db_user = DB_USERNAME;
$db_password = DB_PASSWORD;

$dsn = "{$db_connection}:dbname={$db_name};host={$db_host};port={$db_port};charset=utf8;";

// PDO接続
try {
    $pdo = new PDO($dsn, $db_user, $db_password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
} catch (PDOException $e) {
    echo "接続失敗: " . $e->getMessage();
    exit;
}

接続テストプログラム

DB設定やPDO接続結果を表示します。

connect_test.php
<?php
// 設定ファイル読み込み
require_once 'env.php';

// 変数設定
$db_connection = DB_CONNECTION;
$db_name = DB_DATABASE;
$db_host = DB_HOST;
$db_port = DB_PORT;
$db_user = DB_USERNAME;
$db_password = DB_PASSWORD;

// DSN設定
$dsn = "{$db_connection}:dbname={$db_name};host={$db_host};port={$db_port};charset=utf8;";

// PDO接続
try {
    $pdo = new PDO($dsn, $db_user, $db_password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
} catch (PDOException $e) {
    echo "接続失敗: " . $e->getMessage();
    exit;
}
?>

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PDO Test</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body>
    <main class="mx-auto bg-white shadow-md p-6 rounded-md">
        <h2 class="text-2xl text-center p-2">接続情報</h2>
        <div class="grid grid-cols-2 gap-2 bg-gray-200 p-2 rounded-md">
            <div>DB_CONNECTION</div>
            <div><?= $db_connection ?></div>
            <div>DB_DATABASE</div>
            <div><?= $db_name ?></div>
            <div>DB_HOST</div>
            <div><?= $db_host ?></div>
            <div>DB_PORT</div>
            <div><?= $db_port ?></div>
            <div>DB_USERNAME</div>
            <div><?= $db_user ?></div>
            <div>DB_PASSWORD</div>
            <div><?= $db_password ?></div>
        </div>

        <h2 class="text-2xl text-center p-2">PDO</h2>
        <div class="bg-gray-200 p-2 rounded-md">
            <?= var_dump($pdo) ?>
        </div>
    </main>
</body>

</html>

接続確認

connect_test.phpにアクセスして確認してみましょう。

接続成功の場合

接続失敗の場合

接続が失敗すると以下のようなエラーになります。

結果
接続失敗: SQLSTATE[HY000] [2002] Connection refused

「接続失敗」と表示される場合は、以下を確かめてみましょう。

  • MySQLサーバが起動しているか
  • データベース名、ホストがあっているか
  • ユーザ名、パスワードがあっているか

クラスモジュール化

PDO処理のクラス化する意味

WebアプリではDB接続処理は何度も利用されるため、クラスモジュール化して使いやすいようにします。

理由 説明
🧹 重複コード削減 毎回 new PDO() せずに処理を集約
♻️ 再利用性 アプリ内でどこでも同じ接続ロジック(DRY原則)
🧯 エラー処理の一元化 try/catch を毎回書かなくてよい
🛡️ セキュリティ SQLインジェクション対策がしやすい
🔧 設定切替 本番/開発環境でDB接続先を簡単に切り替えられる
🧪 テストしやすくなる モックやスタブを使ってテストできる構造にしやすい
🚀 パフォーマンスの向上 シングルトン化で無駄なDB接続防止

☠️ クラス化しないと…

DB接続処理をいろんなファイルに書くと、以下のような長いコードを毎回記述しないといけません。

$dsn = "{$db_connection}:dbname={$db_name};host={$db_host};port={$db_port};charset=utf8;";
try {
    $pdo = new PDO($dsn, $db_user, $db_password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
} catch (PDOException $e) {
    echo "接続失敗: " . $e->getMessage();
    exit;
}

$pdo->prepare(...);
...
  • コピペ地獄
  • 設定変更が面倒
  • バグが増える&修正しにくい

✅ クラスモジュール化すると…

DB接続処理をクラスモジュール化すると、短いコードで効率的にバグを減らせます。

$pdo = Database::getInstance();
$pdo->prepare(...);
...
  • どこでも同じ方法で接続できる
  • 接続ミスが起きにくい
  • 管理・テストもラク

クラスファイル作成

ファイル構成

basic
├── env.php
├── lib
|    └── Database.php
└── connect_test_for_module.php

lib フォルダに Database クラスを作成します。

スタティック変数

PDOクラスにスタティック変数 pdo を設定します。この pdo を外部から使いまわせるようにします。

Database.php
<?php
class Database
{
    // PDO変数(スタティック)
    private static $pdo;
}

シングルトンパターン

シングルトン(Singleton)は、アプリケーション内で1つのインスタンスしか存在しないようにするデザインパターンです。同じオブジェクトを何度呼び出しても同じインスタンスが返るのが特徴です。

pdo のシングルトン

DB接続オブジェクトの pdo をシングルトンするプログラムを実装します。

Database.php
<?php
class Database
{
    private static ?PDO $pdo = null;

    public static function getInstance(): PDO
    {
        if (self::$pdo === null) {
            // 設定読み込み
            $db_connection = DB_CONNECTION;
            $db_name = DB_DATABASE;
            $db_host = DB_HOST;
            $db_port = DB_PORT;
            $db_user = DB_USERNAME;
            $db_password = DB_PASSWORD;

            // DSN
            $dsn = "{$db_connection}:dbname={$db_name};host={$db_host};port={$db_port};charset=utf8;";
            // DP接続(try-catchで例外処理)
            try {
                self::$pdo = new PDO($dsn, $db_user, $db_password);
                self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                self::$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            } catch (PDOException $e) {
                die("接続失敗: " . $e->getMessage());
            }
        }
        // シングルトンパターンでPDOインスタンスを返す
        return self::$pdo;
    }
}

PDO接続

DB設定とクラスモジュールを読み込み、DB接続をします。

connect_test_for_module.php
<?php
// env.php ファイルの読み込み
require_once 'env.php';
// Database.php ファイルの読み込み
require_once 'Database.php';

// PDOインスタンスを取得
$pdo = Database::getInstance();

接続テストプログラム

DB設定やPDO接続結果を表示します。

connect_test_for_module.php
<?php
// env.php ファイルの読み込み
require_once 'env.php';
// Database.php ファイルの読み込み
require_once 'Database.php';

// PDOインスタンスを取得
$pdo = Database::getInstance();
?>

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PDO Test</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body>
<main class="mx-auto bg-white shadow-md p-6 rounded-md">
        <h2 class="text-2xl text-center p-2">接続情報</h2>
        <div class="grid grid-cols-2 gap-2 bg-gray-200 p-2 rounded-md">
            <div>DB_CONNECTION</div>
            <div><?= $db_connection ?></div>
            <div>DB_DATABASE</div>
            <div><?= $db_name ?></div>
            <div>DB_HOST</div>
            <div><?= $db_host ?></div>
            <div>DB_PORT</div>
            <div><?= $db_port ?></div>
            <div>DB_USERNAME</div>
            <div><?= $db_user ?></div>
            <div>DB_PASSWORD</div>
            <div><?= $db_password ?></div>
        </div>

        <h2 class="text-2xl text-center p-2">PDO</h2>
        <div class="bg-gray-200 p-2 rounded-md">
            <?= var_dump($pdo) ?>
        </div>
    </main>
</body>

</html>

接続確認

connect_test_for_module.phpにアクセスして確認してみましょう。

PHP + MySQL Webサーバプログラミング