Appearance
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_noが1のデータを取ってきてみましょう。
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_noに1をバインドするため、'post_no' => 1としています。
別に'post_no' => 2とか'post_no' => $変数名とかでも大丈夫です。
③ の説明
③ のところで、execute()メソッドを呼び出しています。
第一引数には、① で用意した SQL 文を渡します。第二引数には、② で用意したバインドする値を渡します。
クラス内で、この値をよしなに扱い、いい感じに実行してくれます。
値をアップデートする
続いて、contentテーブルのpost_noが1のデータを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 "成功したよ!";
}