Cum să personalizați clasa wpdb și să adăugați metode noi
Publicat: 2018-07-10Stratul de abstractizare a bazei de date WordPress, cunoscut mai frecvent ca wpdb, este o clasă bazată pe ezSQL responsabilă de interacțiunea cu baza de date. Clasa wpdb este, de asemenea, un drop-in – o bucată de cod de bază WP care poate fi înlocuită cu ușurință cu o altă bucată de cod cu funcționalitate similară (o listă actualizată de drop-in-uri este disponibilă în WP Code Reference).
Modificarea clasei implicite #wpdb nu este complicată. Puteți adăuga, elimina sau modifica cu ușurință doar câteva metode. Nu este nevoie să înlocuiți întreaga clasă. #wordpress
CLICK PENTRU A TWETEAici intervine o mare concepție greșită. Oamenii percep „înlocuit” ca în „scrie propria clasă de bază de date completă”. Din fericire, nu trebuie să scrieți întreaga clasă a bazei de date. Puteți lua clasa existentă și puteți adăuga, elimina sau modifica doar funcțiile de care aveți nevoie. Și asta vom face.
De ce modificați clasa wpdb?
Sigur, wpdb are tot ce ai nevoie!? Întregul WP este construit deasupra acestuia. Tehnic este corect. Folosind metoda $wpdb->query()
puteți executa orice comandă SQL. Dar cu această logică aplicată nu am avea niciodată sau nu am avea nevoie de metode precum $wpdb->insert()
sau $wpdb->get_var()
. Dar o facem, deoarece economisesc timp, reduc erorile și țin la distanță interogările proaste. Deci, ce funcții lipsesc? Asta depinde de proiectul la care lucrezi. Aveam nevoie de suport pentru aceste două întrebări:
INSERT IGNORE INTO tbl_name ...
INSERT INTO tbl_name ... ON DUPLICATE KEY UPDATE ...
Pasul #1 - Creați drop-in-ul
Procesul de creare a unui drop-in DB este simplu, iar rezultatul final se îmbină perfect în WP.
Creați un fișier numit db.php
și plasați-l în folderul /wp-content/
. Dați fișierului un antet de plugin standard și creați o clasă care extinde wpdb. Ceva de genul:
<?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();
Antetul este destul de explicit. Metoda de construcție se asigură că creăm o nouă conexiune DB odată ce un obiect este construit și folosește constructorul original wpdb pentru asta. Aceste constante DB sunt definite în wp-config.php
. După cum am spus la început, doar adăugăm câteva funcții și reutilizam orice altceva. A doua metodă test()
este doar pentru a vedea dacă totul funcționează corect.
Ultimele două rânduri sunt cruciale. Deoarece aceasta este o clasă personalizată, WP nu va crea automat obiectul $wpdb
pentru noi. Trebuie să o facem noi înșine. Nu uitați să utilizați cuvântul cheie global
, deoarece, altfel, veți crea o variabilă locală.
Pasul #2 – Testează înainte de a săpa mai adânc
Deschideți WP Dashboard și mergeți la Plugins. Pe lângă filele obișnuite Toate, Activ și Inactiv (plugin-uri), veți vedea o filă Drop-in și în ea, printr-o oarecare magie, clasa noastră de baze de date personalizată.
Deoarece administratorul funcționează corect, știm că am făcut o treabă bună. Noua noastră clasă, personalizată și extinsă este în curs și nu s-a schimbat nimic. Grozav! Dar, pentru o bună măsură, puneți aceste trei linii de cod în functions.php
ale temei (sau undeva în interiorul unui plugin unde va fi rulat imediat):

global $wpdb; $wpdb->test(); die;
Rulați orice pagină de administrator sau front-end și ce vedeți? „ Extended wpdb rulează. " Perfect. Acum pentru funcțiile noastre din lumea reală.
Pasul #3 - Creați, modificați sau înlocuiți funcții
Interogarea INSERT IGNORE
pare destul de ușor de făcut. Avem deja $wpdb->insert() așa că ne lipsește doar un singur cuvânt. Din păcate, din cauza lipsei filtrelor în locurile potrivite, nu vor fi două linii de cod.
Dacă deschideți wp-db.php și mergeți la metoda insert()
de pe linia #2100, veți vedea că folosește metoda _insert_replace_helper()
din linia #2151. Și această funcție nu are un singur filtru sau acțiune. Nu putem include nici funcția pentru că returnează imediat rezultatul interogării și nu interogarea în sine pe care am putea-o modifica. Păcat. Va trebui să suprascriem ambele metode insert()
și _insert_replace_helper()
. Vom adăuga un parametru suplimentar – $ignore
. Un boolean cu valoarea implicită false
.
public function insert( $table, $data, $format = null, $ignore = false ) { return $this->_insert_replace_helper( $table, $data, $format, 'INSERT', $ignore = false ); }
În orice altă circumstanță, o funcție care are cinci parametri ar fi un bun candidat pentru a-i transforma într-o matrice asociativă. Dar vrem compatibilitate inversă, așa că nu facem asta. Modificările la cealaltă funcție sunt și ele minore:
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 ) ); }
De ce dezvoltatorii nu fac asta mai des?
Dacă aveți nevoie de o interogare personalizată doar de câteva ori, puteți utiliza cu ușurință $wpdb->query()
. Nu este nevoie să înlocuiți clasa implicită. De asemenea, puteți scrie o clasă personalizată care o extinde pe cea implicită, dar care nu înlocuiește obiectul wpdb. În acest caz, ați folosi $mycustomclass->method()
, dar acesta nu este sfârșitul lumii.
Pe lângă factorul de răceală evident, extinderea clasei implicite wpdb este ceva care este menit să fie făcut în WP și nu este hackish, așa că nu ezitați să vă jucați cu el. Ține cont de două lucruri:
- când trimiteți proiectul cuiva, nu uitați să includeți fișierul
db.php
; nu va fi în nicio temă sau folder de plugin - fii atent la modificările din
wp-db.php
, deoarece acestea ar putea afecta clasa ta personalizată (deși acest lucru este foarte puțin probabil)