はじめに
WordPressはデータベースへの操作を行う場合、デフォルトの$wpdb
クラスを使います。
しかし$wpdb
クラスを使わずにデータベースへアクセスするには、PDO(PHP Data Objects)というのを使います。
PDOはWordPressに限らず、PHPが使えれば何でも使えるので覚えて損はないものです。
この記事では、WordPressのfunctions.php
でPDOを使用してデータベースにアクセスする方法を紹介します。
PDO の接続をセットアップ
まず、functions.php
に以下のコードを追加してPDOでのデータベース接続をセットアップします。
<?php
function pdo_connect() {
$host = DB_HOST;
$db = DB_NAME;
$user = DB_USER;
$pass = DB_PASSWORD;
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
return new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
}
?>
PDOを使ってデータを取得
次に、PDOを使ってデータベースからデータを取得する関数を作成します。
<?php
function fetch_posts_with_pdo() {
$pdo = pdo_connect();
$stmt = $pdo->query('SELECT post_title, post_content FROM wp_posts WHERE post_type="post" AND post_status="publish"');
while ($row = $stmt->fetch()) {
echo '<h2>' . $row['post_title'] . '</h2>';
echo '<p>' . $row['post_content'] . '</p>';
}
}
?>
実際にデータを表示
最後に、テーマファイルやショートコードなどでfetch_posts_with_pdo()
関数を呼び出して、投稿のタイトルと内容を表示します。
ソースコードの解説
上記ソースコードについて解説します。
PDOはAjaxなどと同じくパッと見では理解するのが難しいので、小分けで解説していきます。
<?php
function pdo_connect() {
$host = DB_HOST;
$db = DB_NAME;
$user = DB_USER;
$pass = DB_PASSWORD;
$charset = 'utf8mb4';
/* 省略 */
}
この部分では、WordPressの設定ファイル(wp-config.php
)で定義されているデータベースの接続情報を取得しています。
DB_HOSTDB_NAME
、DB_USER
、DB_PASSWORD
はそれぞれデータベースのホスト名、データベース名、ユーザー名、パスワードを表しています。
<?php
function pdo_connect() {
/* 省略 */
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
/* 省略 */
}
ここで、PDOの接続文字列(DSN:Data Source Name)を作成しています。この文字列は、PDO がどのようなデータベースに接続するかを指定するためのものです。この場合、MySQL データベースに接続します。
<?php
function pdo_connect() {
/* 省略 */
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
/* 省略 */
}
$options
配列では、PDOの接続オプションを設定しています。
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
:エラーモードを設定し、エラーが発生した場合には例外をスローします。PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
:デフォルトのフェッチモードを連想配列として設定します。PDO::ATTR_EMULATE_PREPARES => false
:エミュレーションモードのプリペアードステートメントを無効にします。これは、特定の SQL インジェクション攻撃を防ぐためのものです。
<?php
function pdo_connect() {
/* 省略 */
try {
return new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
/* 省略 */
}
この部分では、try-catch
ブロックを使用してPDOのインスタンスを作成し、データベースに接続します。
もし接続に失敗した場合、例外をキャッチしてエラーメッセージをスローします。
<?php
function fetch_posts_with_pdo() {
$pdo = pdo_connect();
$query = "SELECT post_title, post_content FROM wp_posts WHERE post_type = 'post' AND post_status = 'publish'";
/* 省略 */
}
先ほど解説した pdo_connect
関数を使用して、PDO のインスタンスを取得しています。
このインスタンスを使用して、データベースの操作を行います。
次の行ではSQLクエリを準備しています。
具体的には、wp_posts
テーブルから最新の10件の記事タイトル (post_title
) と内容 (post_content
) を取得するクエリです。
ただし、取得する投稿は投稿タイプが post(通常のブログ投稿)で、そのステータスが publish(公開済み)であるもののみに限定しています。
このクエリは、PDOの prepare
メソッドを使用して、プリペアードステートメントとして準備されます。
プリペアードステートメントとは、SQLインジェクション攻撃を防ぐための一手段として使用されます。
<?php
function fetch_posts_with_pdo() {
/* 省略 */
while ($row = $stmt->fetch()) {
echo '<h2>' . $row['post_title'] . '</h2>';
echo '<p>' . $row['post_content'] . '</p>';
}
}
while()の条件文では、$row
に取得結果を配列で受け取り、受け取れればwhile()でループし、受け取れなければループせずに終了します。
$row['post_title']
と$row['post_content']
でそれぞれの対応するキーを持つ配列の値を出力します。
コメント