$wpdb->get_results(...) returnează array gol în ciuda interogării corecte
După cum sugerează și titlul, nu reușesc să obțin rezultate de la $wpdb->get_results. Executarea interogării "raw" funcționează, dar acest cod nu returnează rezultate din motive necunoscute.
global $wpdb;
$sql = "SELECT *
FROM something aki,
somethingelse akb,
somethingelseelse ac
WHERE aki.keyID = akb.keyID
AND akb.someID = ac.someID
AND aki.type LIKE '%thing%'";
$corps = $wpdb->get_results($sql, OBJECT);
var_dump($corps);
Folosește $wpdb->show_errors( true )
înainte de interogare și vezi ce eroare primești înapoi.
Problema mea (pentru că am întâmpinat același lucru) a fost că ar fi trebuit să folosesc $wpdb->posts
în loc de wp_posts
în cadrul interogării. Prefixul tabelelor se poate schimba de la o instalare WP la alta sau chiar în aceeași instalare, în funcție de moment (de exemplu, un administrator poate schimba prefixul oricând dorește). Așadar, ar trebui să scrii interogarea astfel:
$query = "select <stuff here> from $wpdb->posts where <stuff here>";

Am depanat un script care producea un array gol în WordPress cu un șir MySQL aparent sănătos. S-a dovedit că, spre deosebire de persoana care a pus întrebarea, eu am folosit $wpdb->prepare(), dar soluția pe care am găsit-o poate fi totuși utilă cuiva care întâlnește acest Q&A (așa cum am pățit eu).
Acest șir, AND aki.type LIKE '%thing%'"
, conține wildcard-uri procentuale (%
) care indică faptul că căutăm celula aki.type
care conține thing
ca parte din valoarea sa.
$wpdb->prepare
le convertește în hash-uri, iar serverul MySQL primește ceva de genul: AND aki.type LIKE '{399038939300d2c307c53b29a166ee90101da7b2aba7978a898694010bf1bfe6}thing{399038939300d2c307c53b29a166ee90101da7b2aba7978a898694010bf1bfe6}'
. Firește, nu s-ar obține niciun rezultat!
Pagina wpdb::prepare menționează: 'Semnele procentuale literale (%) din șirul de interogare trebuie scrise ca %%. Wildcard-urile procentuale (de exemplu, pentru a fi folosite în sintaxa LIKE) trebuie transmise printr-un argument de substituție care conține șirul LIKE complet, acestea nu pot fi inserate direct în șirul de interogare. Vezi și wpdb::esc_like().'
Deci, partea LIKE
trebuie pregătită astfel (exemplu de pe pagina wpdb::esc_like()):
$wild = '%';
$find = 'doar 43% din planete';
$like = $wild . $wpdb->esc_like( $find ) . $wild;
$sql = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE %s", $like );
Unde $wpdb->esc_like()
ar trebui să fie folosit înainte de $wpdb->prepare()
.
Și dacă cineva dorește să înlocuiască manual placeholder-ele pentru wildcard-uri procentuale, ar trebui să folosească $wpdb->remove_placeholder_escape() după $wpdb->prepare()
.

Postez acest comentariu aici deoarece interogarea din întrebare este foarte asemănătoare cu ce aveam eu, deși nu era imediat evident că în cazul meu problema era în $wpdb->prepare()
. Cred că altcineva ar putea ajunge pe această pagină cu aceeași problemă.

Problema ta este oarecum similară, dar nu la fel ca întrebarea originală. Suger să deschizi o nouă întrebare și apoi să o răspunzi (este încurajat să îți răspunzi singur la întrebare). Apoi poți marca răspunsul tău ca fiind cel acceptat, iar cei care au probleme cu $wpdb->prepare()
(spre deosebire de $wpdb->get_results()
) pot găsi mai ușor întrebarea și răspunsul tău.

Am înțeles, Pat J. Crezi că ar trebui să las acest răspuns aici sau să îl șterg?

Aș spune să-l lași așa. Dacă un administrator consideră că nu este potrivit, îl poate elimina.

gata https://wordpress.stackexchange.com/q/406772/190417

S-ar putea să fie puțin târziu, dar îți lipsește apelul "prepare" necesar în WordPress:
$Table_Name = $wpdb->prefix.'Numele Tabelului Tău';
$sql_query = $wpdb->prepare("SELECT * FROM $Table_Name WHERE aki.keyID=%d AND akb.someID=%d AND aki.type like %s", akb.keyID, ac.someID, ''%thing%');
$result = $wpdb->query( $sql_query );
Mai multe rezultate pot fi găsite în array.

A menționat că a greșit numele tabelului mai sus. Apelul $wpdb->prepare() nu este necesar pentru o interogare care este complet statică și nu provine de la utilizator, așa că nu este probabil să fie util aici. În orice caz, linia ta cu prepare() de mai sus conține cod care nu este PHP.

Pentru căutările numerice nu... dar pentru căutările de șiruri în mySQL, este necesar un set diferit de parametri pe care apelul prepare îl face pentru tine. Altfel, trebuie să inserezi '%s%' în jurul șirului. Dacă nu faci asta, căutarea în mysql eșuează.

Corect, dar ai înțeles greșit. „Static” înseamnă neschimbător, adică o interogare bazată în întregime pe text fix, cu variabile inserate. Interogarea afișată era text fix (adică „static”), așa că folosirea prepare nu adaugă nimic. Cu toate acestea, este o practică bună să folosești prepare() atunci când interpolezi valori într-o interogare (adică dinamică sau non-statică). Noroc!

Am avut aceeași problemă, un statement SQL bun, fără erori, dar fără rezultate folosind wpdb.
Soluția pentru mine a fost să am collația/codarea caracterelor corectă (de ex. COLLATE 'utf8_general_ci') pentru tabela mea.
Aveam o interogare care funcționa, tabela a fost înlocuită cu un dump de pe un alt server (și mai vechi) și interogarea mea a încetat să mai funcționeze. Returna NULL sau 0 chiar dacă rulând interogarea direct în baza de date returna rezultatele corecte.
Am creat tabelele în ambele moduri (de câteva ori pentru că nu-mi venea să cred), am rulat același script de inserare a datelor și nu am schimbat codul PHP/wpdb.
Când tabela a fost creată cu aceasta, interogarea mea NU a funcționat.
CREATE TABLE IF NOT EXISTS `vf_user` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`email` varchar(50) NOT NULL,
`full_name` varchar(25) NOT NULL,
`password` varchar(25) NOT NULL,
`role` enum('user','tester','admin') NOT NULL DEFAULT 'user',
`phone` varchar(25) NOT NULL,
`last_modified` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`user_activation_key` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `email` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=325 DEFAULT CHARSET=utf8 COMMENT='users table';
Când a fost creată cu aceasta, interogarea mea a returnat rezultate
CREATE TABLE `vf_user` (
`id` MEDIUMINT(9) NOT NULL AUTO_INCREMENT,
`email` VARCHAR(50) NOT NULL COLLATE 'utf8_general_ci',
`full_name` VARCHAR(25) NOT NULL COLLATE 'utf8_general_ci',
`password` VARCHAR(25) NOT NULL COLLATE 'utf8_general_ci',
`role` ENUM('user','tester','admin') NOT NULL DEFAULT 'user' COLLATE 'utf8_general_ci',
`phone` VARCHAR(25) NOT NULL COLLATE 'utf8_general_ci',
`last_modified` TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`user_activation_key` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `email` (`email`) USING BTREE
)
COMMENT='utilizatori cu acces la festivalul virtual'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=325
;

Funcția wpdb->get_results
din WordPress returnează rezultatul dacă este executată cu succes, altfel va returna null. Pot exista mai multe motive pentru care o interogare eșuează. Consultați articolul detaliat despre depanare get_results() returnează rezultate goale aici.
Deși poți utiliza funcții precum wpdb->show_error()
pentru a verifica care a fost ultima eroare după executarea interogării SQL, uneori această eroare poate returna gol. În acest caz, încearcă să folosești wpdb->last_query
pentru a verifica interogarea finală care a fost generată.
