{"id":229589,"date":"2022-11-06T10:47:00","date_gmt":"2022-11-06T07:47:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229589"},"modified":"2022-11-09T08:36:01","modified_gmt":"2022-11-09T05:36:01","slug":"consultas-do-wordpress-com-clausulas-in-quem-sabia","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/consultas-do-wordpress-com-clausulas-in-quem-sabia\/","title":{"rendered":"Consultas do WordPress com cl\u00e1usulas IN (quem sabia)?"},"content":{"rendered":"\n<p>H\u00e1 pouco mais de um ano, escrevi um post sobre como usar o <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> sempre que voc\u00ea tiver <a href=\"https:\/\/tommcfarlin.com\/wp_query-and-multiple-meta-keys\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">um conjunto de chaves<\/a> que deseja usar para ajudar a recuperar informa\u00e7\u00f5es do banco de dados.<\/p>\n<p>E quanto ao caso, por\u00e9m, quando voc\u00ea tem v\u00e1rias chaves diferentes que resultariam na cria\u00e7\u00e3o de uma matriz muito longa para a classe <strong>WP_Meta_Query<\/strong>? Por exemplo, e se voc\u00ea tivesse que percorrer uma cole\u00e7\u00e3o de dados antes mesmo de configurar a consulta?<\/p>\n<p>Em algum n\u00edvel, pode parecer que a coisa natural a fazer seria:<\/p>\n<ol>\n<li>iterar atrav\u00e9s da cole\u00e7\u00e3o de chaves,<\/li>\n<li>construir dinamicamente os resultados,<\/li>\n<li>combin\u00e1-los em um \u00fanico conjunto de resultados,<\/li>\n<li>ent\u00e3o trabalhe com o que for dado.<\/li>\n<\/ol>\n<p>Mas isso n\u00e3o soa um pouco complicado (quanto mais lento)?<\/p>\n<p>Quando se trata de usar a API do WordPress, fa\u00e7o o que posso para me ater a ela antes de falar, digamos, diretamente com o banco de dados, mas tamb\u00e9m h\u00e1 momentos em que faz sentido escrever uma consulta bruta do que escrever algum tipo de c\u00f3digo inteligente apenas para que a API do WordPress funcione.<\/p>\n<p>Antes de entrar no racioc\u00ednio de por que fiz as coisas que fiz, quero explicar o problema e a abordagem. Isso provavelmente evitar\u00e1 que algu\u00e9m entre nos coment\u00e1rios prematuramente.<\/p>\n<p>Esta captura de tela n\u00e3o tem nada a ver com a consulta. Apenas uma foto do IDE por divers\u00e3o.<\/p>\n<p>Ent\u00e3o aqui vai:<\/p>\n<ul>\n<li>Eu tenho uma matriz padr\u00e3o de valores que s\u00e3o eventualmente usados \u200b\u200bpara ajudar a obter metadados e criar um tipo de postagem personalizado a partir deles (porque eles foram importados de uma fonte de terceiros).<\/li>\n<li>Eu sou um grande defensor da parametriza\u00e7\u00e3o de consultas (e, portanto, usando <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>) para garantir que os dados sejam consultados corretamente no banco de dados. Infelizmente, isso n\u00e3o estava acontecendo ao tentar executar esta consulta. Vou explicar o porqu\u00ea mais adiante neste post.<\/li>\n<li>Assim, pegar a matriz e convert\u00ea-la em uma string \u00e9 \u00fatil, mas ainda n\u00e3o resolve o problema de por que a\u00a0 fun\u00e7\u00e3o de <strong>prepara\u00e7\u00e3o<\/strong> padr\u00e3o n\u00e3o estava funcionando.<\/li>\n<\/ul>\n<p>Dito isso, vou explicar algumas coisas:<\/p>\n<ol>\n<li>por que optei por usar um array para armazenar valores de metadados,<\/li>\n<li>por que usei <a href=\"https:\/\/php.net\/manual\/en\/function.implode.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">implode<\/a> para convert\u00ea-los em uma string,<\/li>\n<li>por que n\u00e3o estou usando <strong>prepare<\/strong> para lidar com a consulta.<\/li>\n<\/ol>\n<h3>Sobre valores de metadados<\/h3>\n<p>A raz\u00e3o para manter metadados em um array como uma propriedade da classe \u00e9 porque esse array pode mudar com o tempo.<\/p>\n<p>Ou seja, podemos precisar importar dados adicionais de terceiros, precisaremos remover dados de terceiros ou podemos precisar fazer algumas modifica\u00e7\u00f5es no que estiver presente.<\/p>\n<p>Quando esses dados s\u00e3o mantidos em um \u00fanico local, fica muito mais f\u00e1cil gerenciar vers\u00f5es futuras do c\u00f3digo.<\/p>\n<h3>Implodindo a matriz<\/h3>\n<p>Sempre que voc\u00ea estiver executando uma consulta no banco de dados e precisar trabalhar com uma matriz de dados, poder\u00e1 usar <strong>WP_Meta_Query<\/strong> e usar cada chave como parte da matriz de argumentos.<\/p>\n<p>Mas se voc\u00ea tem um conjunto relativamente grande de dados, primeiro voc\u00ea precisa percorrer todos eles, criar a consulta e process\u00e1-la.<\/p>\n<p>E uma vez que voc\u00ea tenha feito tudo isso, n\u00e3o estou convencido de que o c\u00f3digo que foi escrito n\u00e3o tenha prejudicado o desempenho. \u00c9 por isso que, \u00e0s vezes, opto por usar <a href=\"https:\/\/codex.wordpress.org\/Class_Reference\/wpdb\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wpdb<\/a>.<\/p>\n<h3>N\u00e3o usando Preparar<\/h3>\n<p>Agora, ao fazer interface diretamente com o banco de dados, tento ter certeza:<\/p>\n<ol>\n<li>Eu tenho uma boa raz\u00e3o para faz\u00ea-lo,<\/li>\n<li>Estou usando consultas parametrizadas.<\/li>\n<\/ol>\n<p>Mas eu tenho trabalhado com esse conjunto espec\u00edfico de dados por um tempo tentando usar todas as permuta\u00e7\u00f5es do desenvolvimento do WordPress que eu conhe\u00e7o (incluindo conversar com v\u00e1rios colegas sobre isso) para tentar fazer isso funcionar da melhor maneira poss\u00edvel.<\/p>\n<p>Mas n\u00e3o estava acontecendo. E foi a\u00ed que me deparei com a seguinte p\u00e1gina <a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/esc_sql\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">no Codex<\/a> :<\/p>\n<blockquote>\n<p>Em 99% dos casos, voc\u00ea pode usar $wpdb-&gt;prepare() em vez disso, e esse \u00e9 o m\u00e9todo recomendado. Esta fun\u00e7\u00e3o \u00e9 apenas para uso nos raros casos em que voc\u00ea n\u00e3o pode usar facilmente $wpdb-&gt;prepare(). Um exemplo \u00e9 preparar um array para uso em uma cl\u00e1usula IN.<\/p>\n<\/blockquote>\n<p>E era exatamente isso que eu estava tentando fazer: eu estava procurando pesquisar a meta-tabela de postagem onde os valores da meta-chave estavam contidos em uma matriz.<\/p>\n<p>Ent\u00e3o aqui est\u00e1 como eu resolvi tudo isso.<\/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\">Primeiro<\/a>, criei um array para conter as v\u00e1rias meta-chaves que sei que eventualmente precisarei mapear (embora o valor das chaves n\u00e3o importe para o prop\u00f3sito deste 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\">Ent\u00e3o<\/a> eu os converti em uma string pronta para MySQL. Concedido, isso n\u00e3o \u00e9 entrada do usu\u00e1rio e est\u00e1 sendo usado em uma\u00a0 cl\u00e1usula <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>, portanto, n\u00e3o pode ser usado em uma\u00a0 instru\u00e7\u00e3o <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\">Por fim<\/a>, criei a consulta e recuperei os resultados:<\/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>E foi assim que acabei trabalhando com os arrays, a propriedade de classe e configurando minha consulta.<\/p>\n<p>Esta \u00e9 a melhor maneira de trabalhar com consultas do WordPress com cl\u00e1usulas IN? N\u00e3o tenho certeza, mas dada a minha experi\u00eancia, o que li e como est\u00e1 funcionando, estou feliz com o resultado final.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte de grava\u00e7\u00e3o:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Trabalhar com consultas do WordPress com cl\u00e1usulas IN pode ser complicado, especialmente se voc\u00ea estiver lidando com meta-chaves. Aqui est\u00e1 o que eu encontrei para trabalhar.<\/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":[722,920,806,867],"tags":[1170],"class_list":["post-229589","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desenvolvedor","category-outro","category-php-8","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/229589","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/comments?post=229589"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/229589\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/166518"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=229589"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=229589"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=229589"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}