$wpdb->get_results(...) returnează array gol în ciuda interogării corecte

22 sept. 2014, 08:14:28
Vizualizări: 18K
Voturi: 9

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);
9
Comentarii

Ai încercat să rulezi această interogare direct în phpmyadmin?

TBI Infotech TBI Infotech
22 sept. 2014 08:15:31

Da, atât în phpmyadmin cât și în mysql shell direct. Funcționează în ambele. Totuși, nu obțin rezultate (array gol) în $wpdb->get_results

1Up 1Up
22 sept. 2014 08:40:15

Nu reușesc să identific problema exactă. Dar poți face debugging folosind-o fără al doilea parametru OBJECT și utilizând o interogare simplă, apoi adăugând condiții. Astfel vei putea identifica problema

TBI Infotech TBI Infotech
22 sept. 2014 08:49:04

Adăugând la comentariul lui @TBIInfotech, îți amintești să folosești prefixul WP pe tabelele tale acolo unde este relevant?

Joshua Joshua
22 sept. 2014 09:25:09

Arrrr... Tocmai am folosit $wpdb->show_errors( true ) înainte de interogare și am primit eroarea înapoi. Se pare că WP a început să codeze caracterul ' în interiorul interogărilor brusc și fără motiv... Ar putea fi și motivul problemelor tale. Poate ar fi bine să transmiți '%thing%' ca parametru către get_reults.

NoOne NoOne
27 feb. 2016 21:44:42

În final, problema mea s-a dovedit a fi că ar fi trebuit să folosesc $wpdb->posts în loc de wp_posts în interogare. Presupun că, cumva, fără niciun motiv aparent, tabelele din baza de date de pe serverul nostru au fost redenumite? WTF?!?!?!

NoOne NoOne
27 feb. 2016 22:03:10

@NoOne Dacă ai rezolvat problema, te rog să postezi un răspuns și să-l accepți :) (va opri această întrebare să apară în lista noastră de întrebări fără răspuns). Ar trebui să folosești întotdeauna prefixul setat mai degrabă decât să te bazezi că va fi mereu wp_

Tim Malone Tim Malone
28 iun. 2016 01:42:03

@TimMalone Nu este întrebarea mea, așa că nu o pot accepta. Dar voi posta un răspuns. Asta ar putea ajuta unele persoane... ;)

NoOne NoOne
30 iun. 2016 19:35:10

@NoOne Ha ha corect. Mulțumesc pentru postarea răspunsului! Încerc să rezolv lista de întrebări fără răspuns momentan ;)

Tim Malone Tim Malone
30 iun. 2016 22:24:00
Arată celelalte 4 comentarii
Toate răspunsurile la întrebare 5
0

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>";
27 feb. 2016 21:46:48
5

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().

14 iun. 2022 10:18:21
Comentarii

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ă.

Artem Artem
14 iun. 2022 10:24:40

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.

Pat J Pat J
14 iun. 2022 18:08:12

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

Artem Artem
14 iun. 2022 18:55:22

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

Pat J Pat J
14 iun. 2022 20:44:50
3

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.

6 mar. 2019 01:27:14
Comentarii

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.

Brian C Brian C
11 apr. 2020 07:31:20

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ă.

Debbie Kurth Debbie Kurth
13 apr. 2020 00:49:30

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!

Brian C Brian C
13 apr. 2020 10:04:04
0

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
;
25 nov. 2020 12:05:48
0

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ă.

6 aug. 2021 20:24:08