Skip to content

DB 操作用クラス

DB の操作、面倒だし、毎回書くのめんどくさいので、クラスを用意しました。 良ければ使ってください。

クラス

php
<?php

/**
 * Dbクラス
 * データベース接続およびトランザクション管理を提供します。
 */
class Db
{
    /** @var PDO $pdo PDOインスタンス */
    private $pdo;

    private const DB_HOST = 'localhost';
    private const DB_CHARSET = 'utf8mb4';
    private const DB_NAME = 'bbs_sample1';
    private const DB_USER = 'syskai_user';
    private const DB_PASS = 'syskai_pass';

    /** @var array $error 最後のエラー情報 */
    private $error = array(
        "isError" => false,
        "raw" => null
    );

    /**
     * オブジェクトのシリアライズ時に空の配列を返す。
     * @return array 空の配列
     */
    public function __sleep()
    {
        return array();
    }

    /**
     * オブジェクトのデシリアライズ時にコンストラクタを再呼び出す。
     */
    public function __wakeup()
    {
        $this->__construct();
    }

    /**
     * Dbクラスのコンストラクタ。
     * DBへの接続を試みます。
     */
    public function __construct()
    {
        try {
            $dsn = 'mysql:host=' . self::DB_HOST . ';dbname=' . self::DB_NAME . ';charset=' . self::DB_CHARSET . ';';
            $this->pdo = new PDO($dsn, self::DB_USER, self::DB_PASS);
            $this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
        } catch (PDOException $e) {
            $this->setError($e->errorInfo);
            die();
        }
    }

    /**
     * トランザクションの開始。
     * @return bool 成功時:true、失敗時:false
     */
    public function beginTransaction()
    {
        return $this->pdo->beginTransaction();
    }

    /**
     * トランザクションのコミット。
     * @return bool 成功時:true、失敗時:false
     */
    public function commit()
    {
        return $this->pdo->commit();
    }

    /**
     * トランザクションのロールバック。
     * @return bool 成功時:true、失敗時:false
     */
    public function rollBack()
    {
        return $this->pdo->rollBack();
    }

    /**
     * 直近のエラー情報を取得。
     * @return false|array 正常時:false、異常時:エラー情報の配列
     */
    public function getError(): bool
    {
        if ($this->error["isError"] === true) {
            return $this->error["raw"];
        } else {
            return false;
        }
    }

    /**
     * 直近で挿入した行のPrimaryKeyを取得。
     * @return false|string 成功時:PrimaryKey、失敗時:false
     */
    public function getLastInsertId()
    {
        try {
            $val = $this->pdo->lastInsertId();
        } catch (PDOException $e) {
            $this->setError($e->errorInfo);
            $val = false;
        }

        return $val;
    }

    /**
     * PDO::prepareのラッパー。
     * @param string $sql SQL文
     * @return PDOStatement|bool 成功時:PDOStatementオブジェクト、失敗時:false
     */
    public function prepare(string $sql)
    {
        $this->clearError();

        try {
            $stmt = $this->pdo->prepare($sql);
            return $stmt;
        } catch (PDOException $e) {
            $this->setError($e->errorInfo);
            return false;
        }
    }

    /**
     * プレースホルダー付きSQLを実行。
     * @param string $sql 実行するSQL文
     * @param array $ary バインドする値の配列
     * @return PDOStatement|bool SELECTクエリかWITHクエリの場合:PDOStatement、その他のクエリの場合:true、エラー時:false
     */
    public function execute(string $sql, array $ary = array())
    {
        $this->clearError();

        try {
            $stmt = $this->prepare($sql);
            if ($stmt == false) {
                return false;
            }

            $execResult = $stmt->execute($ary);
            if ($execResult == false) {
                $this->setError($stmt->errorInfo());
                return false;
            }

            if (preg_match('/^select/i', trim($sql))||preg_match('/^with/i', trim($sql))) {
                return $stmt;
            } else {
                return true;
            }
        } catch (PDOException $e) {
            $this->setError($e->errorInfo);
            return false;
        }
    }

    /**
     * エラー情報を設定。
     * @param array $errorInfo エラー情報の配列
     */
    private function setError($errorInfo): void
    {
        $this->error["isError"] = true;
        $this->error["raw"] = $errorInfo;
    }

    /**
     * エラー情報をクリア。
     */
    private function clearError(): void
    {
        $this->error["isError"] = false;
        $this->error["raw"] = null;
    }
}
<?php

/**
 * Dbクラス
 * データベース接続およびトランザクション管理を提供します。
 */
class Db
{
    /** @var PDO $pdo PDOインスタンス */
    private $pdo;

    private const DB_HOST = 'localhost';
    private const DB_CHARSET = 'utf8mb4';
    private const DB_NAME = 'bbs_sample1';
    private const DB_USER = 'syskai_user';
    private const DB_PASS = 'syskai_pass';

    /** @var array $error 最後のエラー情報 */
    private $error = array(
        "isError" => false,
        "raw" => null
    );

    /**
     * オブジェクトのシリアライズ時に空の配列を返す。
     * @return array 空の配列
     */
    public function __sleep()
    {
        return array();
    }

    /**
     * オブジェクトのデシリアライズ時にコンストラクタを再呼び出す。
     */
    public function __wakeup()
    {
        $this->__construct();
    }

    /**
     * Dbクラスのコンストラクタ。
     * DBへの接続を試みます。
     */
    public function __construct()
    {
        try {
            $dsn = 'mysql:host=' . self::DB_HOST . ';dbname=' . self::DB_NAME . ';charset=' . self::DB_CHARSET . ';';
            $this->pdo = new PDO($dsn, self::DB_USER, self::DB_PASS);
            $this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
        } catch (PDOException $e) {
            $this->setError($e->errorInfo);
            die();
        }
    }

    /**
     * トランザクションの開始。
     * @return bool 成功時:true、失敗時:false
     */
    public function beginTransaction()
    {
        return $this->pdo->beginTransaction();
    }

    /**
     * トランザクションのコミット。
     * @return bool 成功時:true、失敗時:false
     */
    public function commit()
    {
        return $this->pdo->commit();
    }

    /**
     * トランザクションのロールバック。
     * @return bool 成功時:true、失敗時:false
     */
    public function rollBack()
    {
        return $this->pdo->rollBack();
    }

    /**
     * 直近のエラー情報を取得。
     * @return false|array 正常時:false、異常時:エラー情報の配列
     */
    public function getError(): bool
    {
        if ($this->error["isError"] === true) {
            return $this->error["raw"];
        } else {
            return false;
        }
    }

    /**
     * 直近で挿入した行のPrimaryKeyを取得。
     * @return false|string 成功時:PrimaryKey、失敗時:false
     */
    public function getLastInsertId()
    {
        try {
            $val = $this->pdo->lastInsertId();
        } catch (PDOException $e) {
            $this->setError($e->errorInfo);
            $val = false;
        }

        return $val;
    }

    /**
     * PDO::prepareのラッパー。
     * @param string $sql SQL文
     * @return PDOStatement|bool 成功時:PDOStatementオブジェクト、失敗時:false
     */
    public function prepare(string $sql)
    {
        $this->clearError();

        try {
            $stmt = $this->pdo->prepare($sql);
            return $stmt;
        } catch (PDOException $e) {
            $this->setError($e->errorInfo);
            return false;
        }
    }

    /**
     * プレースホルダー付きSQLを実行。
     * @param string $sql 実行するSQL文
     * @param array $ary バインドする値の配列
     * @return PDOStatement|bool SELECTクエリかWITHクエリの場合:PDOStatement、その他のクエリの場合:true、エラー時:false
     */
    public function execute(string $sql, array $ary = array())
    {
        $this->clearError();

        try {
            $stmt = $this->prepare($sql);
            if ($stmt == false) {
                return false;
            }

            $execResult = $stmt->execute($ary);
            if ($execResult == false) {
                $this->setError($stmt->errorInfo());
                return false;
            }

            if (preg_match('/^select/i', trim($sql))||preg_match('/^with/i', trim($sql))) {
                return $stmt;
            } else {
                return true;
            }
        } catch (PDOException $e) {
            $this->setError($e->errorInfo);
            return false;
        }
    }

    /**
     * エラー情報を設定。
     * @param array $errorInfo エラー情報の配列
     */
    private function setError($errorInfo): void
    {
        $this->error["isError"] = true;
        $this->error["raw"] = $errorInfo;
    }

    /**
     * エラー情報をクリア。
     */
    private function clearError(): void
    {
        $this->error["isError"] = false;
        $this->error["raw"] = null;
    }
}

使い方

このクラスのいいところは、エラーハンドリングを try-catch で行わなくても良い点です。
戻り値が false の場合は、エラーが発生しているので、getError()メソッドでエラー情報が確認できます。

DB から全データを取ってくる(SELECT)

では、contentテーブルから、すべてのデータを取ってきてみましょう。

php
<?php
// 上で書いたクラスをロードする。
require_once('Db.php');

// DBクラスを実体化する
$db = new Db();

// SQL文を用意する
$sql = 'SELECT * FROM `content`';

// SQLを実行する
$stmt = $db->execute($sql,array()); // <--- 1

if($stmt===false){
  // エラーのとき
  echo "エラーだよ。内容は→".$db->getError();
}else{
  // 成功のとき
  $result = $stmt->fetchAll();  // 取得結果の全件を取ってくる。
  var_dump($result);            // 内容を画面出力
}
<?php
// 上で書いたクラスをロードする。
require_once('Db.php');

// DBクラスを実体化する
$db = new Db();

// SQL文を用意する
$sql = 'SELECT * FROM `content`';

// SQLを実行する
$stmt = $db->execute($sql,array()); // <--- 1

if($stmt===false){
  // エラーのとき
  echo "エラーだよ。内容は→".$db->getError();
}else{
  // 成功のとき
  $result = $stmt->fetchAll();  // 取得結果の全件を取ってくる。
  var_dump($result);            // 内容を画面出力
}

① のところで、execute()メソッドを呼び出しています。
第二引数には、SQL 文のプレースホルダーにバインドする値を配列で渡します。今回はバインドする必要がないので、空の配列(array())を渡しています。

DB から post_no が〇〇を取ってくる(SELECT)

続いて、contentテーブルから、post_no1のデータを取ってきてみましょう。

php
<?php
// 上で書いたクラスをロードする。
require_once('Db.php');

// DBクラスを実体化する
$db = new Db();

// ①:SQL文を用意する
$sql = 'SELECT * FROM `content` WHERE `post_no` = :post_no';

// ②:バインドする値を用意する
$ary = array(
  'post_no' => 1
);

// ③:SQLを実行する
$stmt = $db->execute($sql,$ary);

if($stmt===false){
  // エラーのとき
  echo "エラーだよ。内容は→".$db->getError();
}else{
  // 成功のとき
  $result = $stmt->fetchAll();  // 取得結果の全件を取ってくる。
  var_dump($result);            // 内容を画面出力
}
<?php
// 上で書いたクラスをロードする。
require_once('Db.php');

// DBクラスを実体化する
$db = new Db();

// ①:SQL文を用意する
$sql = 'SELECT * FROM `content` WHERE `post_no` = :post_no';

// ②:バインドする値を用意する
$ary = array(
  'post_no' => 1
);

// ③:SQLを実行する
$stmt = $db->execute($sql,$ary);

if($stmt===false){
  // エラーのとき
  echo "エラーだよ。内容は→".$db->getError();
}else{
  // 成功のとき
  $result = $stmt->fetchAll();  // 取得結果の全件を取ってくる。
  var_dump($result);            // 内容を画面出力
}

① の説明

① のところで、SQL 文を用意します。プレースホルダーを用いることで、SQL インジェクションを防ぎます。置き換える文字列は:〇〇〇のように、コロン(:)をつけておきます。
今回はpost_noをバインドするので、:post_noとしていますが、別に他の名前でも大丈夫です。

② の説明

② のところは、① で用意した SQL 文のプレースホルダーにバインドする値を用意します。一例としてpost_no1をバインドするため、'post_no' => 1としています。
別に'post_no' => 2とか'post_no' => $変数名とかでも大丈夫です。

③ の説明

③ のところで、execute()メソッドを呼び出しています。
第一引数には、① で用意した SQL 文を渡します。第二引数には、② で用意したバインドする値を渡します。
クラス内で、この値をよしなに扱い、いい感じに実行してくれます。

値をアップデートする

続いて、contentテーブルのpost_no1のデータを2にアップデートしてみましょう。

php
// 上で書いたクラスをロードする。
require_once('Db.php');

// DBクラスを実体化する
$db = new Db();

// SQL文を用意する
$sql = 'UPDATE `content` SET `post_no` = :new_postno WHERE `post_no` = :old_postno';
$ary = array(
  "new_postno" => 2,
  "old_postno" => 1
);

// SQLを実行する
$stmt = $db->execute($sql,$ary);

// 実行成否を判定する
if($stmt===false){
  // エラーのとき
  echo "エラーだよ。内容は→".$db->getError();
}else{
  // 成功のとき
  echo "成功したよ!";
}
// 上で書いたクラスをロードする。
require_once('Db.php');

// DBクラスを実体化する
$db = new Db();

// SQL文を用意する
$sql = 'UPDATE `content` SET `post_no` = :new_postno WHERE `post_no` = :old_postno';
$ary = array(
  "new_postno" => 2,
  "old_postno" => 1
);

// SQLを実行する
$stmt = $db->execute($sql,$ary);

// 実行成否を判定する
if($stmt===false){
  // エラーのとき
  echo "エラーだよ。内容は→".$db->getError();
}else{
  // 成功のとき
  echo "成功したよ!";
}