{"id":229860,"date":"2022-11-06T11:09:00","date_gmt":"2022-11-06T08:09:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229860"},"modified":"2022-11-09T16:42:26","modified_gmt":"2022-11-09T13:42:26","slug":"query-wordpress-con-clausole-in-chi-sapeva","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/it\/query-wordpress-con-clausole-in-chi-sapeva\/","title":{"rendered":"Query WordPress con clausole IN (chi sapeva)?"},"content":{"rendered":"\n<p>Poco pi\u00f9 di un anno fa, ho scritto un post su come utilizzare <strong><a href=\"https:\/\/codex.wordpress.org\/Class_Reference\/WP_Meta_Query\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WP_Meta_Query<\/a><\/strong> ogni volta che si dispone di <a href=\"https:\/\/tommcfarlin.com\/wp_query-and-multiple-meta-keys\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">un set di chiavi<\/a> che si desidera utilizzare per recuperare informazioni dal database.<\/p>\n<p>Che dire del caso, tuttavia, quando si dispone di un numero di chiavi diverse che risulterebbe nella creazione di un array molto lungo per la classe <strong>WP_Meta_Query<\/strong>? Ad esempio, cosa succede se dovessi scorrere una raccolta di dati prima ancora di impostare la query?<\/p>\n<p>A un certo livello, potrebbe sembrare che la cosa naturale da fare sarebbe:<\/p>\n<ol>\n<li>scorrere la raccolta di chiavi,<\/li>\n<li>costruire dinamicamente i risultati,<\/li>\n<li>combinarli in un unico set di risultati,<\/li>\n<li>quindi lavora con tutto ci\u00f2 che ti viene dato.<\/li>\n<\/ol>\n<p>Ma non suona un po&#8217; ingombrante (per non parlare di lento)?<\/p>\n<p>Quando si tratta di utilizzare l&#8217;API di WordPress, faccio il possibile per attenermi ad essa prima di parlare, ad esempio, direttamente al database, ma ci sono anche momenti in cui ha senso scrivere una query grezza piuttosto che scrivere un tipo di codice intelligente semplicemente per far funzionare l&#8217;API di WordPress.<\/p>\n<p>Prima di entrare nella logica del perch\u00e9 ho fatto le cose che ho, voglio spiegare il problema e l&#8217;approccio. Questo probabilmente salver\u00e0 qualcuno dal saltare prematuramente nei commenti.<\/p>\n<p>Questo screenshot non ha nulla a che fare con la query. Solo una foto dell&#8217;IDE per divertimento.<\/p>\n<p>Quindi ecco qui:<\/p>\n<ul>\n<li>Ho una matrice standard di valori che vengono eventualmente utilizzati per aiutare a prendere i metadati e creare un tipo di post personalizzato da essi (perch\u00e9 sono stati importati da una fonte di terze parti).<\/li>\n<li>Sono un grande sostenitore della parametrizzazione delle query (e quindi dell&#8217;utilizzo di <a href=\"https:\/\/codex.wordpress.org\/Class_Reference\/wpdb#Protect_Queries_Against_SQL_Injection_Attacks\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">prepare<\/a>) per assicurarmi che i dati vengano interrogati correttamente sul database. Sfortunatamente, ci\u00f2 non accadeva durante il tentativo di eseguire questa query. Spiegher\u00f2 perch\u00e9 pi\u00f9 avanti in questo post.<\/li>\n<li>Pertanto, prendere l&#8217;array e convertirlo in una stringa \u00e8 utile, ma non risolve ancora il problema sul motivo per cui la\u00a0 funzione di <strong>preparazione<\/strong> standard non funzionava.<\/li>\n<\/ul>\n<p>Detto questo, ti spiego alcune cose:<\/p>\n<ol>\n<li>perch\u00e9 ho scelto di utilizzare un array per memorizzare i valori dei metadati,<\/li>\n<li>perch\u00e9 ho usato <a href=\"https:\/\/php.net\/manual\/en\/function.implode.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">implode<\/a> per convertirli in una stringa,<\/li>\n<li>perch\u00e9 non sto usando <strong>prepare<\/strong> per gestire la query.<\/li>\n<\/ol>\n<h3>Sui valori dei metadati<\/h3>\n<p>Il motivo per mantenere i metadati in un array come propriet\u00e0 della classe \u00e8 perch\u00e9 questo array potrebbe cambiare nel tempo.<\/p>\n<p>Cio\u00e8, potrebbe essere necessario importare ulteriori dati di terze parti, rimuovere dati di terze parti o apportare alcune modifiche a tutto ci\u00f2 che \u00e8 presente.<\/p>\n<p>Quando questi dati vengono conservati in un unico posto, \u00e8 molto pi\u00f9 semplice gestire le versioni future del codice.<\/p>\n<h3>Implosione dell&#8217;array<\/h3>\n<p>Ogni volta che esegui una query sul database e devi lavorare con una matrice di dati, puoi utilizzare <strong>WP_Meta_Query<\/strong> e utilizzare ciascuna chiave come parte della matrice degli argomenti.<\/p>\n<p>Ma se hai un set di dati relativamente grande, devi prima scorrerlo tutto, quindi devi creare la query, quindi devi elaborarla.<\/p>\n<p>E una volta che hai fatto tutto questo, non sono convinto che il codice che \u00e8 stato scritto non sia andato a scapito delle prestazioni. Questo \u00e8 il motivo per cui, a volte, scelgo di utilizzare <a href=\"https:\/\/codex.wordpress.org\/Class_Reference\/wpdb\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wpdb<\/a>.<\/p>\n<h3>Non utilizzando Prepara<\/h3>\n<p>Ora, interfacciandomi direttamente con il database, cerco di assicurarmi:<\/p>\n<ol>\n<li>Ho una buona ragione per farlo,<\/li>\n<li>Sto usando query parametrizzate.<\/li>\n<\/ol>\n<p>Ma ho lavorato con questo specifico insieme di dati per un po&#8217; cercando di utilizzare ogni permutazione dello sviluppo di WordPress di cui sono a conoscenza (incluso parlarne con diversi colleghi) per cercare di farlo funzionare nel miglior modo possibile.<\/p>\n<p>Non stava succedendo, per\u00f2. Ed \u00e8 allora che mi sono imbattuto nella seguente pagina <a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/esc_sql\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">del Codex<\/a> :<\/p>\n<blockquote>\n<p>Nel 99% dei casi, puoi invece usare $wpdb-&gt;prepare(), e questo \u00e8 il metodo consigliato. Questa funzione \u00e8 da usare solo in quei rari casi in cui non puoi usare facilmente $wpdb-&gt;prepare(). Un esempio \u00e8 la preparazione di un array da utilizzare in una clausola IN.<\/p>\n<\/blockquote>\n<p>Ed \u00e8 esattamente quello che stavo cercando di fare: stavo cercando di cercare nella meta tabella dei post in cui i valori della meta chiave erano contenuti in un array.<\/p>\n<p>Quindi ecco come ho risolto tutto questo.<\/p>\n<p><a href=\"https:\/\/gist.github.com\/tommcfarlin\/d482b2383363558f5647f578e62d25c3#file-00-keys-to-map-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Innanzitutto<\/a>, ho creato un array per contenere le varie meta chiavi che so che alla fine avr\u00f2 bisogno di mappare (sebbene il valore delle chiavi non abbia importanza ai fini di questo post):<\/p>\n<pre><code>&lt;?php\n\n\/\/ This is used to maintain a map of data should we need to add more.\n$data_types = [\n    'data_item_one',\n    'data_item_two',\n    '...'\n    'data_item_ten,\n];\n<\/code><\/pre>\n<p><a href=\"https:\/\/gist.github.com\/tommcfarlin\/d482b2383363558f5647f578e62d25c3#file-01-mysql-ready-string-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Quindi<\/a> li ho convertiti in una stringa pronta per MySQL. Certo, questo non \u00e8 l&#8217;input dell&#8217;utente e viene utilizzato in una\u00a0 clausola <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/5.7\/en\/comparison-operators.html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">IN<\/a>, quindi non pu\u00f2 essere utilizzato in\u00a0 un&#8217;istruzione <strong>prepare<\/strong> :<\/p>\n<pre><code>&lt;?php\n\n\/**\n * Converts the incoming array into a comma-delimited string with\n * quotes wrapped around each key.\n *\n * @access private\n *\n * @param  array $arr The array to convert to a string.\n * @return string     The string representation of the array delimited by quotes and commas.\n *\/\nprivate function convert_to_sql_ready_string( $arr) {\n  return '\"'. implode( $arr, '\",\"' ). '\"';\n}\n<\/code><\/pre>\n<p><a href=\"https:\/\/gist.github.com\/tommcfarlin\/d482b2383363558f5647f578e62d25c3#file-02-the-query-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Infine<\/a>, ho creato la query e recuperato i risultati:<\/p>\n<pre><code>&lt;?php\n\npublic function get_data_values() {\n\n  global $wpdb;\n  $query = \"\n    SELECT post_id, meta_key, meta_value \n    FROM $wpdb-&gt;postmeta WHERE\n    meta_key in ($this-&gt;data_types) AND \n    meta_value &lt;&gt; '';\n  \";\n\n  $results = $wpdb-&gt;get_results( $query );\n\n  return $results;\n}\n<\/code><\/pre>\n<p>Ed \u00e8 cos\u00ec che ho finito per lavorare con gli array, la propriet\u00e0 della classe e per impostare la mia query.<\/p>\n<p>\u00c8 questo il modo migliore per lavorare con le query di WordPress con clausole IN? Non ne sono sicuro, ma data la mia esperienza, quello che ho letto e come sta funzionando, sono contento del risultato finale.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte di registrazione:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lavorare con le query di WordPress con le clausole IN pu\u00f2 essere complicato soprattutto se hai a che fare con meta chiavi. Ecco cosa ho trovato per funzionare.<\/p>\n","protected":false},"author":1,"featured_media":166518,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[918,804,720,865],"tags":[1168],"class_list":["post-229860","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-altro","category-php-6","category-sviluppatore","category-wordpress-6","tag-affiai-it"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/229860","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/comments?post=229860"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/229860\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media\/166518"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media?parent=229860"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/categories?post=229860"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/tags?post=229860"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}