直接触ると言ってもより便利に操作できるよう、ラッパーオブジェクトが用意されているため、それを使用する。
グローバルオブジェクトとして定義されている $wpdb を使用する。
まずは定義を行う。

global $wpdb; /** @var wpdb $wpdb */

SELECT文の例

$wpdb->get_results の第二引数には、返り値の形式を指定できる。

$query = "SELECT * FROM $wpdb->posts ORDER BY ID LIMIT 20;";

// $rows = $wpdb->get_results($query, OBJECT); と同義でオブジェクトを指定
$rows = $wpdb->get_results($query); 
foreach($rows as $row) {
   $id = $row->ID; // オブジェクトで返ってくる
}

$rows = $wpdb->get_results($query, ARRAY_A); // 連想配列の指定
foreach($rows as $row) {
   $id = $row['ID'];
}

$rows = $wpdb->get_results($query, ARRAY_N); // 数字添え字
foreach($rows as $row) {
   $id = $row[0]; // 0: ID
   $id = $row[1]; // 1: post_title
}

// 値を一つだけ取る場合は、$wpdb->get_var()を使用
$count = $wpdb->get_var($query);

プリペアドステートメント

SQLインジェクション対策として $wpdb->prepare() 関数によりプレースホルダーが使用可能。
プレースホルダーとして指定された値は、エスケープされる。
変数を使う場合はこちらを必ず利用する。

// %d -> 整数
// $s -> 文字列
// $f -> 小数
$query = "SELECT count(*) FROM $wpdb->posts WHERE post_type = %s ORDER BY ID LIMIT 20;";
$prepared = $wpdb->prepare($query, 'hoge');
$count = $wpdb->get_var($prepared);

トランザクション

トランザクションを行う場合は、テーブルをロックする必要があるが、WordPressの場合、テーブル間が密に関連しているため、関連するテーブルを一括でロックしたほうが楽。

$lockedTableList = [];
foreach ($wpdb->tables('hoge') as $table) {
  $lockedTableList[]= $table . ' WRITE';
}
$query = 'LOCK TABLES '.implode(', ', $lockedTableList).';';
$wpdb->query($query);

概要図

とてもよくまとまっていた図があったので、拝借させていただいた。

https://one-ap-engineer.com/wpdb/