{"id":229203,"date":"2022-11-06T11:30:00","date_gmt":"2022-11-06T08:30:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229203"},"modified":"2022-11-09T05:56:59","modified_gmt":"2022-11-09T02:56:59","slug":"consultas-de-wordpress-con-clausulas-in-quien-sabia","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/consultas-de-wordpress-con-clausulas-in-quien-sabia\/","title":{"rendered":"Consultas de WordPress con cl\u00e1usulas IN (\u00bfQui\u00e9n sab\u00eda)?"},"content":{"rendered":"\n<p>Hace poco m\u00e1s de un a\u00f1o, escrib\u00ed una publicaci\u00f3n sobre c\u00f3mo usar <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> siempre que tenga <a href=\"https:\/\/tommcfarlin.com\/wp_query-and-multiple-meta-keys\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">un conjunto de claves<\/a> que quiera usar para ayudar a recuperar informaci\u00f3n de la base de datos.<\/p>\n<p>Sin embargo, \u00bfqu\u00e9 pasa con el caso, cuando tiene varias claves diferentes que dar\u00edan como resultado la creaci\u00f3n de una matriz realmente larga para la clase <strong>WP_Meta_Query<\/strong>? Por ejemplo, \u00bfqu\u00e9 pasar\u00eda si tuviera que recorrer una colecci\u00f3n de datos incluso antes de configurar la consulta?<\/p>\n<p>En alg\u00fan nivel, podr\u00eda parecer que lo m\u00e1s natural ser\u00eda:<\/p>\n<ol>\n<li>iterar a trav\u00e9s de la colecci\u00f3n de claves,<\/li>\n<li>construir din\u00e1micamente los resultados,<\/li>\n<li>combinarlos en un \u00fanico conjunto de resultados,<\/li>\n<li>luego trabaja con lo que te den.<\/li>\n<\/ol>\n<p>\u00bfPero no suena un poco engorroso (y mucho menos lento)?<\/p>\n<p>Cuando se trata de usar la API de WordPress, hago lo que puedo para ce\u00f1irme a ella antes de hablar, por ejemplo, directamente con la base de datos, pero tambi\u00e9n hay momentos en los que tiene sentido escribir una consulta sin formato que escribir alg\u00fan tipo de c\u00f3digo inteligente simplemente para que la API de WordPress funcione.<\/p>\n<p>Antes de entrar en la justificaci\u00f3n de por qu\u00e9 hice las cosas que hice, quiero explicar el problema y el enfoque. Es probable que esto evite que alguien salte a los comentarios prematuramente.<\/p>\n<p>Esta captura de pantalla no tiene nada que ver con la consulta. Solo una foto del IDE por diversi\u00f3n.<\/p>\n<p>As\u00ed que aqu\u00ed va:<\/p>\n<ul>\n<li>Tengo una matriz est\u00e1ndar de valores que eventualmente se usan para ayudar a tomar metadatos y crear un tipo de publicaci\u00f3n personalizado a partir de ellos (porque se han importado de una fuente de terceros).<\/li>\n<li>Soy un gran defensor de la parametrizaci\u00f3n de consultas (y, por lo tanto, del uso de la <a href=\"https:\/\/codex.wordpress.org\/Class_Reference\/wpdb#Protect_Queries_Against_SQL_Injection_Attacks\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">preparaci\u00f3n<\/a>) para asegurarme de que los datos se consultan correctamente en la base de datos. Desafortunadamente, esto no suced\u00eda al intentar ejecutar esta consulta. Explicar\u00e9 por qu\u00e9 m\u00e1s adelante en este post.<\/li>\n<li>Por lo tanto, tomar la matriz y convertirla en una cadena es \u00fatil, pero a\u00fan no resuelve el problema de por qu\u00e9 la\u00a0 funci\u00f3n de <strong>preparaci\u00f3n<\/strong> est\u00e1ndar no funcionaba.<\/li>\n<\/ul>\n<p>Dicho esto, voy a explicar algunas cosas:<\/p>\n<ol>\n<li>por qu\u00e9 opt\u00e9 por usar una matriz para almacenar valores de metadatos,<\/li>\n<li>por qu\u00e9 he usado\u00a0 la <a href=\"https:\/\/php.net\/manual\/en\/function.implode.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">implosi\u00f3n<\/a> para convertirlos en una cadena,<\/li>\n<li>por qu\u00e9 no estoy usando <strong>preparar<\/strong> para manejar la consulta.<\/li>\n<\/ol>\n<h3>Sobre valores de metadatos<\/h3>\n<p>La raz\u00f3n para mantener los metadatos en una matriz como una propiedad de la clase es que esta matriz puede cambiar con el tiempo.<\/p>\n<p>Es decir, es posible que necesitemos importar datos de terceros adicionales, eliminar datos de terceros o hacer algunas modificaciones a lo que est\u00e9 presente.<\/p>\n<p>Cuando estos datos se guardan en un solo lugar, es mucho m\u00e1s f\u00e1cil administrarlos para futuras versiones del c\u00f3digo.<\/p>\n<h3>implosi\u00f3n de la matriz<\/h3>\n<p>Cada vez que ejecuta una consulta en la base de datos y tiene que trabajar con una matriz de datos, puede usar <strong>WP_Meta_Query<\/strong> y usar cada clave como parte de la matriz de argumentos.<\/p>\n<p>Pero si tiene un conjunto de datos relativamente grande, primero debe recorrerlos todos, luego debe crear la consulta y luego debe procesarla.<\/p>\n<p>Y una vez que haya hecho todo eso, no estoy convencido de que el c\u00f3digo que se escribi\u00f3 no haya sido a expensas del rendimiento. Es por eso que, a veces, 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>No usar preparar<\/h3>\n<p>Ahora, cuando interact\u00fao directamente con la base de datos, trato de asegurarme de que:<\/p>\n<ol>\n<li>Tengo una buena raz\u00f3n para hacerlo,<\/li>\n<li>Estoy usando consultas parametrizadas.<\/li>\n<\/ol>\n<p>Pero he estado trabajando con este conjunto espec\u00edfico de datos por un tiempo tratando de usar cada permutaci\u00f3n del desarrollo de WordPress que conozco (incluyendo hablar con varios compa\u00f1eros al respecto) para tratar de hacer que esto funcione de la mejor manera posible.<\/p>\n<p>Sin embargo, no estaba sucediendo. Y fue entonces cuando me top\u00e9 con la siguiente p\u00e1gina <a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/esc_sql\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">en el Codex<\/a> :<\/p>\n<blockquote>\n<p>En el 99% de los casos, puede usar $wpdb-&gt;prepare() en su lugar, y ese es el m\u00e9todo recomendado. Esta funci\u00f3n solo se usa en aquellos casos excepcionales en los que no puede usar f\u00e1cilmente $wpdb-&gt;prepare(). Un ejemplo es preparar una matriz para usarla en una cl\u00e1usula IN.<\/p>\n<\/blockquote>\n<p>Y eso es exactamente lo que estaba tratando de hacer: estaba buscando buscar en la tabla de metadatos de la publicaci\u00f3n donde los valores clave de la metadatos estaban contenidos en una matriz.<\/p>\n<p>As\u00ed que as\u00ed es como resolv\u00ed todo esto.<\/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\">Primero<\/a>, cre\u00e9 una matriz para contener las diversas claves meta que s\u00e9 que eventualmente necesitar\u00e9 mapear (aunque el valor de las claves no importa para el prop\u00f3sito de esta publicaci\u00f3n):<\/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\">Luego<\/a> los convert\u00ed a una cadena lista para MySQL. Por supuesto, esto no es una entrada del usuario y se est\u00e1 usando en una\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>, por lo que no se puede usar en una\u00a0 declaraci\u00f3n de <strong>preparaci\u00f3n<\/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\">Finalmente<\/a>, cre\u00e9 la consulta y recuper\u00e9 los 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>Y as\u00ed es como termin\u00e9 trabajando con las matrices, la propiedad de clase y configurando mi consulta.<\/p>\n<p>\u00bfEs esta la mejor manera de trabajar con consultas de WordPress con cl\u00e1usulas IN? No estoy seguro, pero dada mi experiencia, lo que he le\u00eddo y c\u00f3mo funciona, estoy contento con el resultado final.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fuente de grabaci\u00f3n:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Trabajar con consultas de WordPress con cl\u00e1usulas IN puede ser complicado, especialmente si se trata de claves meta. Esto es lo que encontr\u00e9 para trabajar.<\/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":[716,914,800,861],"tags":[1172],"class_list":["post-229203","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desarrollador","category-otro","category-php-2","category-wordpress-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/229203","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=229203"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/229203\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/166518"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=229203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=229203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=229203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}