XoopsDatabaseクラス
XoopsDatabaseクラスはXOOPSのデータベース抽象化レイヤーを提供し、接続管理、クエリ実行、結果処理、エラー処理を処理します。ドライバーアーキテクチャを通じて複数のデータベースドライバをサポートします。
namespace Xoops\Database;
abstract class XoopsDatabase{ protected $conn; protected $prefix; protected $logger;
abstract public function connect(bool $selectdb = true): bool; abstract public function query(string $sql, int $limit = 0, int $start = 0); abstract public function fetchArray($result): ?array; abstract public function fetchObject($result): ?object; abstract public function getRowsNum($result): int; abstract public function getAffectedRows(): int; abstract public function getInsertId(): int; abstract public function escape(string $string): string;}XoopsDatabase (抽象基底)├── XoopsMySQLDatabase (MySQLエクステンション)│ └── XoopsMySQLDatabaseProxy (セキュリティプロキシ)└── XoopsMySQLiDatabase (MySQLiエクステンション) └── XoopsMySQLiDatabaseProxy (セキュリティプロキシ)
XoopsDatabaseFactory└── 適切なドライバインスタンスを作成データベースインスタンスの取得
Section titled “データベースインスタンスの取得”ファクトリを使用
Section titled “ファクトリを使用”// 推奨: ファクトリを使用$db = XoopsDatabaseFactory::getDatabaseConnection();getInstanceを使用
Section titled “getInstanceを使用”// 代替: 直接シングルトンアクセス$db = XoopsDatabase::getInstance();グローバル変数
Section titled “グローバル変数”// レガシー: グローバル変数を使用global $xoopsDB;コアメソッド
Section titled “コアメソッド”connect
Section titled “connect”データベース接続を確立します。
abstract public function connect(bool $selectdb = true): boolパラメータ:
| パラメータ | 型 | 説明 |
|---|---|---|
$selectdb | bool | データベースを選択するかどうか |
戻り値: bool - 接続成功時はTrue
例:
$db = XoopsDatabaseFactory::getDatabaseConnection();if ($db->connect()) { echo "接続成功";}SQLクエリを実行します。
abstract public function query( string $sql, int $limit = 0, int $start = 0): mixedパラメータ:
| パラメータ | 型 | 説明 |
|---|---|---|
$sql | string | SQLクエリ文字列 |
$limit | int | 返す最大行数 (0 = 制限なし) |
$start | int | 開始オフセット |
戻り値: resource|bool - 結果リソースまたは失敗時はFalse
例:
$db = XoopsDatabaseFactory::getDatabaseConnection();
// シンプルなクエリ$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE uid > 0";$result = $db->query($sql);
// LIMITを付けたクエリ$sql = "SELECT * FROM " . $db->prefix('users');$result = $db->query($sql, 10, 0); // 最初の10行
// オフセット付きクエリ$result = $db->query($sql, 10, 20); // 20行目から10行queryF
Section titled “queryF”クエリを強制実行します (セキュリティチェックをバイパス)。
public function queryF(string $sql, int $limit = 0, int $start = 0): mixedユースケース:
- INSERT、UPDATE、DELETE操作
- 読み取り専用制限をバイパスする必要がある場合
例:
$sql = sprintf( "UPDATE %s SET views = views + 1 WHERE article_id = %d", $db->prefix('articles'), $articleId);$db->queryF($sql);prefix
Section titled “prefix”データベーステーブルプレフィックスを追加します。
public function prefix(string $table = ''): stringパラメータ:
| パラメータ | 型 | 説明 |
|---|---|---|
$table | string | プレフィックスなしのテーブル名 |
戻り値: string - プレフィックス付きのテーブル名
例:
$db = XoopsDatabaseFactory::getDatabaseConnection();
echo $db->prefix('users'); // "xoops_users" (プレフィックスが "xoops_" の場合)echo $db->prefix('modules'); // "xoops_modules"echo $db->prefix(); // "xoops_" (プレフィックスのみ)fetchArray
Section titled “fetchArray”結果行を連想配列として取得します。
abstract public function fetchArray($result): ?arrayパラメータ:
| パラメータ | 型 | 説明 |
|---|---|---|
$result | resource | クエリ結果リソース |
戻り値: array|null - 連想配列または行がない場合はnull
例:
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE level > 0";$result = $db->query($sql);
while ($row = $db->fetchArray($result)) { echo "ユーザー: " . $row['uname'] . "\n"; echo "メール: " . $row['email'] . "\n";}fetchObject
Section titled “fetchObject”結果行をオブジェクトとして取得します。
abstract public function fetchObject($result): ?objectパラメータ:
| パラメータ | 型 | 説明 |
|---|---|---|
$result | resource | クエリ結果リソース |
戻り値: object|null - 各列がプロパティのオブジェクト
例:
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE uid = 1";$result = $db->query($sql);
if ($user = $db->fetchObject($result)) { echo "ユーザー名: " . $user->uname; echo "メール: " . $user->email;}fetchRow
Section titled “fetchRow”結果行を数値配列として取得します。
abstract public function fetchRow($result): ?array例:
$sql = "SELECT uname, email FROM " . $db->prefix('users');$result = $db->query($sql);
while ($row = $db->fetchRow($result)) { echo "ユーザー名: " . $row[0] . ", メール: " . $row[1];}fetchBoth
Section titled “fetchBoth”結果行を連想配列と数値配列の両方として取得します。
abstract public function fetchBoth($result): ?array例:
$result = $db->query($sql);$row = $db->fetchBoth($result);echo $row['uname']; // 名前でアクセスecho $row[0]; // インデックスでアクセスgetRowsNum
Section titled “getRowsNum”結果セット内の行数を取得します。
abstract public function getRowsNum($result): intパラメータ:
| パラメータ | 型 | 説明 |
|---|---|---|
$result | resource | クエリ結果リソース |
戻り値: int - 行数
例:
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE level > 0";$result = $db->query($sql);$count = $db->getRowsNum($result);echo "アクティブなユーザーが見つかりました: $count";getAffectedRows
Section titled “getAffectedRows”最後のクエリで影響を受けた行数を取得します。
abstract public function getAffectedRows(): int戻り値: int - 影響を受けた行数
例:
$sql = "UPDATE " . $db->prefix('users') . " SET last_login = " . time() . " WHERE uid = 1";$db->queryF($sql);$affected = $db->getAffectedRows();echo "更新した行: $affected";getInsertId
Section titled “getInsertId”最後のINSERTで自動生成されたIDを取得します。
abstract public function getInsertId(): int戻り値: int - 最後のINSERT ID
例:
$sql = sprintf( "INSERT INTO %s (title, content) VALUES (%s, %s)", $db->prefix('articles'), $db->quoteString($title), $db->quoteString($content));$db->queryF($sql);$newId = $db->getInsertId();echo "記事を作成しました ID: $newId";escape
Section titled “escape”SQLクエリで安全に使用するための文字列をエスケープします。
abstract public function escape(string $string): stringパラメータ:
| パラメータ | 型 | 説明 |
|---|---|---|
$string | string | エスケープする文字列 |
戻り値: string - エスケープされた文字列 (クォートなし)
例:
$unsafeInput = "O'Reilly";$safe = $db->escape($unsafeInput); // "O\'Reilly"
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE uname = '" . $safe . "'";quoteString
Section titled “quoteString”SQLのための文字列をエスケープしてクォートします。
public function quoteString(string $string): stringパラメータ:
| パラメータ | 型 | 説明 |
|---|---|---|
$string | string | クォートする文字列 |
戻り値: string - エスケープされてクォートされた文字列
例:
$name = "John O'Connor";$quoted = $db->quoteString($name); // "'John O\'Connor'"
$sql = "INSERT INTO users (name) VALUES (" . $quoted . ")";freeRecordSet
Section titled “freeRecordSet”結果に関連するメモリを解放します。
abstract public function freeRecordSet($result): void例:
$result = $db->query($sql);// 結果を処理...$db->freeRecordSet($result); // メモリを解放最後のエラーメッセージを取得します。
abstract public function error(): string例:
$result = $db->query($sql);if (!$result) { echo "データベースエラー: " . $db->error();}最後のエラー番号を取得します。
abstract public function errno(): int例:
$result = $db->query($sql);if (!$result) { echo "エラー #" . $db->errno() . ": " . $db->error();}プリペアドステートメント (MySQLi)
Section titled “プリペアドステートメント (MySQLi)”MySQLiドライバはセキュリティを強化するためのプリペアドステートメントをサポートしています。
prepare
Section titled “prepare”プリペアドステートメントを作成します。
public function prepare(string $sql): mysqli_stmt|false例:
$db = XoopsDatabaseFactory::getDatabaseConnection();
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE uid = ?";$stmt = $db->prepare($sql);
$stmt->bind_param('i', $userId);$userId = 5;$stmt->execute();$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) { echo $row['uname'];}$stmt->close();複数パラメータを使用したプリペアドステートメント
Section titled “複数パラメータを使用したプリペアドステートメント”$sql = "INSERT INTO " . $db->prefix('articles') . " (title, content, author_id) VALUES (?, ?, ?)";$stmt = $db->prepare($sql);
$stmt->bind_param('ssi', $title, $content, $authorId);
$title = "My Article";$content = "Article content here";$authorId = 1;
if ($stmt->execute()) { echo "記事を作成しました ID: " . $stmt->insert_id;}
$stmt->close();トランザクションサポート
Section titled “トランザクションサポート”beginTransaction
Section titled “beginTransaction”トランザクションを開始します。
public function beginTransaction(): boolcommit
Section titled “commit”現在のトランザクションをコミットします。
public function commit(): boolrollback
Section titled “rollback”現在のトランザクションをロールバックします。
public function rollback(): bool例:
$db = XoopsDatabaseFactory::getDatabaseConnection();
try { $db->beginTransaction();
// 複数の操作 $sql1 = "UPDATE " . $db->prefix('accounts') . " SET balance = balance - 100 WHERE id = 1"; $db->queryF($sql1);
$sql2 = "UPDATE " . $db->prefix('accounts') . " SET balance = balance + 100 WHERE id = 2"; $db->queryF($sql2);
// エラーをチェック if ($db->errno()) { throw new Exception($db->error()); }
$db->commit(); echo "トランザクションが完了しました";
} catch (Exception $e) { $db->rollback(); echo "トランザクション失敗: " . $e->getMessage();}完全な使用例
Section titled “完全な使用例”基本的なCRUD操作
Section titled “基本的なCRUD操作”$db = XoopsDatabaseFactory::getDatabaseConnection();
// CREATE (作成)$sql = sprintf( "INSERT INTO %s (title, content, created) VALUES (%s, %s, %d)", $db->prefix('articles'), $db->quoteString('New Article'), $db->quoteString('Article content'), time());$db->queryF($sql);$articleId = $db->getInsertId();
// READ (読み取り)$sql = "SELECT * FROM " . $db->prefix('articles') . " WHERE id = " . (int)$articleId;$result = $db->query($sql);$article = $db->fetchArray($result);
// UPDATE (更新)$sql = sprintf( "UPDATE %s SET title = %s, updated = %d WHERE id = %d", $db->prefix('articles'), $db->quoteString('Updated Title'), time(), $articleId);$db->queryF($sql);
// DELETE (削除)$sql = "DELETE FROM " . $db->prefix('articles') . " WHERE id = " . (int)$articleId;$db->queryF($sql);ページネーションクエリ
Section titled “ページネーションクエリ”function getArticles(int $page = 1, int $perPage = 10): array{ $db = XoopsDatabaseFactory::getDatabaseConnection(); $start = ($page - 1) * $perPage;
// 合計数を取得 $sql = "SELECT COUNT(*) as total FROM " . $db->prefix('articles') . " WHERE published = 1"; $result = $db->query($sql); $row = $db->fetchArray($result); $total = $row['total'];
// 結果ページを取得 $sql = "SELECT * FROM " . $db->prefix('articles') . " WHERE published = 1 ORDER BY created DESC"; $result = $db->query($sql, $perPage, $start);
$articles = []; while ($row = $db->fetchArray($result)) { $articles[] = $row; }
return [ 'articles' => $articles, 'total' => $total, 'pages' => ceil($total / $perPage), 'current' => $page ];}LIKEを使用した検索クエリ
Section titled “LIKEを使用した検索クエリ”function searchArticles(string $keyword): array{ $db = XoopsDatabaseFactory::getDatabaseConnection();
$keyword = $db->escape($keyword); $sql = "SELECT * FROM " . $db->prefix('articles') . " WHERE title LIKE '%" . $keyword . "%'" . " OR content LIKE '%" . $keyword . "%'" . " ORDER BY created DESC";
$result = $db->query($sql, 50); // 最大50件に制限
$articles = []; while ($row = $db->fetchArray($result)) { $articles[] = $row; }
return $articles;}JOINクエリ
Section titled “JOINクエリ”function getArticlesWithAuthors(): array{ $db = XoopsDatabaseFactory::getDatabaseConnection();
$sql = "SELECT a.*, u.uname as author_name, u.email as author_email FROM " . $db->prefix('articles') . " a LEFT JOIN " . $db->prefix('users') . " u ON a.author_id = u.uid WHERE a.published = 1 ORDER BY a.created DESC";
$result = $db->query($sql, 20);
$articles = []; while ($row = $db->fetchArray($result)) { $articles[] = $row; }
return $articles;}SqlUtilityクラス
Section titled “SqlUtilityクラス”SQLファイル操作用のヘルパークラス。
splitMySqlFile
Section titled “splitMySqlFile”SQLファイルを個別のクエリに分割します。
public static function splitMySqlFile(string $content): array例:
$sqlContent = file_get_contents('install.sql');$queries = SqlUtility::splitMySqlFile($sqlContent);
foreach ($queries as $query) { $db->queryF($query); if ($db->errno()) { echo "実行エラー: " . $query . "\n"; echo "エラー: " . $db->error() . "\n"; }}prefixQuery
Section titled “prefixQuery”テーブルプレースホルダーをプレフィックス付きテーブル名に置き換えます。
public static function prefixQuery(string $sql, string $prefix): string例:
$sql = "CREATE TABLE {PREFIX}_articles (id INT PRIMARY KEY)";$prefixedSql = SqlUtility::prefixQuery($sql, $db->prefix());// "CREATE TABLE xoops_articles (id INT PRIMARY KEY)"ベストプラクティス
Section titled “ベストプラクティス”セキュリティ
Section titled “セキュリティ”- 常にユーザー入力をエスケープ:
$safe = $db->escape($_POST['input']);- 利用可能な場合はプリペアドステートメントを使用:
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");$stmt->bind_param('i', $id);- 値にquoteStringを使用:
$sql = "INSERT INTO table (name) VALUES (" . $db->quoteString($name) . ")";パフォーマンス
Section titled “パフォーマンス”- 大きなテーブルには常にLIMITを使用:
$result = $db->query($sql, 100); // 結果を制限- 完了したら結果セットを解放:
$db->freeRecordSet($result);-
テーブル定義に適切なインデックスを使用
-
可能な場合は生SQLより ハンドラーを優先
- 常にエラーをチェック:
$result = $db->query($sql);if (!$result) { trigger_error($db->error(), E_USER_WARNING);}- 複数の関連操作にはトランザクションを使用:
$db->beginTransaction();// ... 操作 ...$db->commit(); // または $db->rollback();関連ドキュメンテーション
Section titled “関連ドキュメンテーション”- Criteria - クエリ条件システム
- QueryBuilder - 流暢なクエリ構築
- ../Core/XoopsObjectHandler - オブジェクト永続化
参照: XOOPSソースコード