wpdbクラスをカスタマイズして新しいメソッドを追加する方法
公開: 2018-07-10WordPressデータベース抽象化レイヤー(より一般的にはwpdbとして知られています)は、データベースとの対話を担当するezSQLに基づくクラスです。 wpdbクラスもドロップインです。コアWPコードの一部であり、同様の機能を備えた別のコードに簡単に置き換えることができます(ドロップインの最新リストはWPコードリファレンスにあります)。
デフォルトの#wpdbクラスの変更は複雑ではありません。 いくつかのメソッドのみを簡単に追加、削除、または変更できます。 クラス全体を置き換える必要はありません。 #wordpress
クリックしてツイートここで大きな誤解が生じます。 人々は、「自分自身の完全なデータベースクラスを作成する」のように「置き換えられた」と認識します。 幸い、データベースクラス全体を作成する必要はありません。 既存のクラスを取得して、必要な機能のみを追加、削除、または変更できます。 そして、それが私たちがやろうとしていることです。
なぜwpdbクラスを変更するのですか?
確かに、wpdbには必要なものがすべて揃っています!? WP全体がその上に構築されています。 技術的には正しいです。 $wpdb->query()メソッドを使用すると、任意のSQLコマンドを実行できます。 しかし、そのロジックを適用すると、 $wpdb->insert()や$wpdb->get_var()のようなメソッドは必要ありません。 しかし、時間を節約し、バグを減らし、悪いクエリを遠ざけるため、私たちはそうします。 では、どの機能が欠けているのでしょうか? それはあなたが取り組んでいるプロジェクトに依存します。 これら2つのクエリのサポートが必要でした。
INSERT IGNORE INTO tbl_name ...
INSERT INTO tbl_name ... ON DUPLICATE KEY UPDATE ...
ステップ1–ドロップインを作成する
DBドロップインを作成するプロセスは単純であり、最終結果はWPにシームレスに溶け込みます。
db.phpという名前のファイルを作成し、それを/wp-content/フォルダーに配置します。 ファイルに標準のプラグインヘッダーを与え、wpdbを拡張するクラスを作成します。 このようなもの:
<?php
/*
Plugin Name: Extended wpdb
Description: A few extra functions for wpdb
Version: 1.0
Author: WebFactory Ltd
*/
class wpdb_extended extends wpdb {
public function __construct(){
parent::__construct( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST );
}
public function test() {
echo 'Extended wpdb is running.';
}
}
global $wpdb;
$wpdb = new wpdb_extended();
ヘッダーはかなり自明です。 構築メソッドは、オブジェクトが構築されたら新しいDB接続を作成し、そのために元のwpdbコンストラクターを使用するようにします。 これらのDB定数は、 wp-config.phpで定義されています。 最初に述べたように、いくつかの関数を追加し、他のすべてを再利用しているだけです。 2番目のメソッドtest()は、純粋にすべてが正しく機能するかどうかを確認するためのものです。
最後の2行は非常に重要です。 これはカスタムクラスであるため、WPは$wpdbオブジェクトを自動的に作成しません。 私たちは自分たちでそれをしなければなりません。 globalキーワードを使用することを忘れないでください。そうしないと、ローカル変数が作成されます。
ステップ2–深く掘り下げる前にテストする
WPダッシュボードを開き、プラグインに移動します。 通常の[すべて]、[アクティブ]、および[非アクティブ(プラグイン)]タブに加えて、[ドロップイン]タブが表示され、その中に、魔法のように、カスタムデータベースクラスが表示されます。
管理者は適切に機能しているので、私たちは良い仕事をしたことを知っています。 新しいカスタムの拡張クラスがあり、何も変更されていません。 素晴らしい! ただし、念のため、これらの3行のコードをテーマのfunctions.php (またはプラグイン内のどこかですぐに実行される場所)に配置します。
global $wpdb; $wpdb->test(); die;
管理者ページまたはフロントエンドページを実行すると、何が表示されますか? 「拡張wpdbが実行されています。 " 完全。 次に、実際の関数について説明します。

ステップ3–関数を作成、変更、または置換する
INSERT IGNOREクエリは非常に簡単に実行できるようです。 すでに$wpdb->insert()があるので、1つの単語が欠落しています。 残念ながら、適切な場所にフィルターがないため、2行のコードにはなりません。
wp-db.phpを開いて、行#2100のinsert()メソッドに進むと、行#2151の_insert_replace_helper()メソッドが使用されていることがわかります。 そして、その関数には単一のフィルターやアクションがありません。 関数をラップすることもできません。これは、変更可能なクエリ自体ではなく、クエリ結果をすぐに返すためです。 残念。 insert() ()メソッドと_insert_replace_helper()メソッドの両方をオーバーライドする必要があります。 追加のパラメーター$ignoreを追加します。 デフォルト値がfalseのブール値。
public function insert( $table, $data, $format = null, $ignore = false ) {
return $this->_insert_replace_helper( $table, $data, $format, 'INSERT', $ignore = false );
}
他の状況では、5つのパラメーターを持つ関数は、それらを連想配列に変換するのに適した候補です。 ただし、下位互換性が必要なため、そのようなことはしていません。 他の機能への変更もマイナーです:
function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT', $ignore = false ) {
$this->insert_id = 0;
if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) ) {
return false;
}
$data = $this->process_fields( $table, $data, $format );
if ( false === $data ) {
return false;
}
$formats = $values = array();
foreach ( $data as $value ) {
if ( is_null( $value['value'] ) ) {
$formats[] = 'NULL';
continue;
}
$formats[] = $value['format'];
$values[] = $value['value'];
}
$fields = '`' . implode( '`, `', array_keys( $data ) ) . '`';
$formats = implode( ', ', $formats );
// modification for IGNORE keyword
if (true == $ignore && 'INSERT' == $type) {
$type = 'INSERT IGNORE';
}
$sql = "$type INTO `$table` ($fields) VALUES ($formats)";
$this->check_current_query = false;
return $this->query( $this->prepare( $sql, $values ) );
}
なぜ開発者はこれをもっと頻繁にしないのですか?
カスタムクエリが数回だけ必要な場合は、 $wpdb->query()を簡単に使用できます。 デフォルトのクラスを置き換える必要はありません。 デフォルトのクラスを拡張するが、wpdbオブジェクトをオーバーライドしないカスタムクラスを作成することもできます。 その場合、 $mycustomclass->method()を使用しますが、それは世界の終わりではありません。
デフォルトのwpdbクラスを拡張する明らかなクールさの要素に加えて、WPで実行されることを意図したものであり、ハックではないので、気軽に試してみてください。 次の2つの点に注意してください。
- プロジェクトを誰かに送信するときは、
db.phpファイルを含めることを忘れないでください。 テーマやプラグインフォルダには含まれません - カスタムクラスに影響を与える可能性があるため、
wp-db.php変更に注意してください(ただし、その可能性はほとんどありません)。
