{"id":228930,"date":"2022-11-06T10:43:00","date_gmt":"2022-11-06T07:43:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=228930"},"modified":"2022-11-09T04:51:00","modified_gmt":"2022-11-09T01:51:00","slug":"zapytania-wordpress-z-klauzulami-in-kto-wiedzial","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/zapytania-wordpress-z-klauzulami-in-kto-wiedzial\/","title":{"rendered":"Zapytania WordPress z klauzulami IN (kto wiedzia\u0142)?"},"content":{"rendered":"\n<p>Nieco ponad rok temu napisa\u0142em post o tym, jak u\u017cywa\u0107 <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>, gdy masz <a href=\"https:\/\/tommcfarlin.com\/wp_query-and-multiple-meta-keys\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">zestaw kluczy<\/a>, kt\u00f3rych chcesz u\u017cy\u0107, aby pom\u00f3c w odzyskaniu informacji z bazy danych.<\/p>\n<p>A co z przypadkiem, gdy masz wiele r\u00f3\u017cnych kluczy, kt\u00f3re skutkowa\u0142yby utworzeniem naprawd\u0119 d\u0142ugiej tablicy dla klasy <strong>WP_Meta_Query<\/strong>? Na przyk\u0142ad, co by by\u0142o, gdyby\u015b musia\u0142 przej\u015b\u0107 przez zbi\u00f3r danych przed skonfigurowaniem zapytania?<\/p>\n<p>Na pewnym poziomie mo\u017ce si\u0119 wydawa\u0107, \u017ce naturaln\u0105 rzecz\u0105 do zrobienia by\u0142oby:<\/p>\n<ol>\n<li>iterowa\u0107 przez kolekcj\u0119 kluczy,<\/li>\n<li>dynamicznie budowa\u0107 wyniki,<\/li>\n<li>po\u0142\u0105czy\u0107 je w jeden zestaw wynik\u00f3w,<\/li>\n<li>nast\u0119pnie pracuj z tym, co otrzymasz.<\/li>\n<\/ol>\n<p>Ale czy to nie brzmi troch\u0119 niepor\u0119cznie (nie m\u00f3wi\u0105c ju\u017c o powolnym)?<\/p>\n<p>Je\u015bli chodzi o korzystanie z API WordPress, robi\u0119, co w mojej mocy, aby si\u0119 go trzyma\u0107, zanim porozmawiam, powiedzmy, bezpo\u015brednio z baz\u0105 danych, ale s\u0105 te\u017c sytuacje, w kt\u00f3rych sensowne jest napisanie surowego zapytania ni\u017c napisanie jakiego\u015b sprytnego kodu aby uruchomi\u0107 API WordPress.<\/p>\n<p>Zanim przejd\u0119 do uzasadnienia, dlaczego zrobi\u0142em to, co zrobi\u0142em, chc\u0119 wyja\u015bni\u0107 problem i podej\u015bcie. Prawdopodobnie uchroni to kogo\u015b przed przedwczesnym wskakiwaniem do komentarzy.<\/p>\n<p>Ten zrzut ekranu nie ma nic wsp\u00f3lnego z zapytaniem. Tylko uj\u0119cie IDE dla zabawy.<\/p>\n<p>Wi\u0119c prosz\u0119 bardzo:<\/p>\n<ul>\n<li>Mam standardow\u0105 tablic\u0119 warto\u015bci, kt\u00f3re s\u0105 ostatecznie u\u017cywane do pomocy w pobieraniu metadanych i tworzeniu z nich niestandardowego typu postu (poniewa\u017c zosta\u0142y zaimportowane z zewn\u0119trznego \u017ar\u00f3d\u0142a).<\/li>\n<li>Jestem wielkim zwolennikiem parametryzacji zapyta\u0144 (a tym samym u\u017cywania <a href=\"https:\/\/codex.wordpress.org\/Class_Reference\/wpdb#Protect_Queries_Against_SQL_Injection_Attacks\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">przygotowania<\/a> ), aby upewni\u0107 si\u0119, \u017ce dane s\u0105 poprawnie odpytywane w bazie danych. Niestety tak si\u0119 nie sta\u0142o podczas pr\u00f3by wykonania tego zapytania. Wyja\u015bni\u0119 dlaczego w dalszej cz\u0119\u015bci tego postu.<\/li>\n<li>Tak wi\u0119c we\u017a tablic\u0119 i przekonwertuj j\u0105 na ci\u0105g znak\u00f3w jest pomocna, ale nadal nie rozwi\u0105zuje problemu, dlaczego standardowa\u00a0 funkcja <strong>przygotowania<\/strong> nie dzia\u0142a\u0142a.<\/li>\n<\/ul>\n<p>Powiedziawszy to, wyja\u015bni\u0119 kilka rzeczy:<\/p>\n<ol>\n<li>dlaczego zdecydowa\u0142em si\u0119 u\u017cy\u0107 tablicy do przechowywania warto\u015bci metadanych,<\/li>\n<li>dlaczego u\u017cy\u0142em <a href=\"https:\/\/php.net\/manual\/en\/function.implode.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">implode<\/a> do konwersji ich na \u0142a\u0144cuch,<\/li>\n<li>dlaczego nie u\u017cywam <strong>przygotowania<\/strong> do obs\u0142ugi zapytania.<\/li>\n<\/ol>\n<h3>O warto\u015bciach metadanych<\/h3>\n<p>Powodem przechowywania metadanych w tablicy jako w\u0142a\u015bciwo\u015bci klasy jest to, \u017ce ta tablica mo\u017ce si\u0119 zmienia\u0107 w czasie.<\/p>\n<p>Oznacza to, \u017ce by\u0107 mo\u017ce b\u0119dziemy musieli zaimportowa\u0107 dodatkowe dane os\u00f3b trzecich, b\u0119dziemy musieli usun\u0105\u0107 dane os\u00f3b trzecich lub mo\u017cemy wprowadzi\u0107 pewne modyfikacje w tym, co jest obecne.<\/p>\n<p>Przechowywanie tych danych w jednym miejscu znacznie u\u0142atwia zarz\u0105dzanie przysz\u0142ymi wersjami kodu.<\/p>\n<h3>Imploduj\u0105ca tablica<\/h3>\n<p>Za ka\u017cdym razem, gdy uruchamiasz zapytanie wzgl\u0119dem bazy danych i musisz pracowa\u0107 z tablic\u0105 danych, mo\u017cesz u\u017cy\u0107 <strong>WP_Meta_Query<\/strong> i u\u017cy\u0107 ka\u017cdego klucza jako cz\u0119\u015bci tablicy argument\u00f3w.<\/p>\n<p>Ale je\u015bli masz stosunkowo du\u017cy zestaw danych, to najpierw musisz je wszystkie przej\u015b\u0107 w p\u0119tli, potem utworzy\u0107 zapytanie, a potem je przetworzy\u0107.<\/p>\n<p>A kiedy ju\u017c to wszystko zrobisz, nie jestem przekonany, \u017ce napisany kod nie powsta\u0142 kosztem wydajno\u015bci. Dlatego czasami decyduj\u0119 si\u0119 na u\u017cycie <a href=\"https:\/\/codex.wordpress.org\/Class_Reference\/wpdb\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wpdb<\/a>.<\/p>\n<h3>Nie u\u017cywam przygotowania<\/h3>\n<p>Teraz, gdy \u0142\u0105czymy si\u0119 bezpo\u015brednio z baz\u0105 danych, staram si\u0119 upewni\u0107:<\/p>\n<ol>\n<li>mam ku temu dobry pow\u00f3d,<\/li>\n<li>U\u017cywam zapyta\u0144 parametrycznych.<\/li>\n<\/ol>\n<p>Ale od jakiego\u015b czasu pracuj\u0119 z tym konkretnym zestawem danych, pr\u00f3buj\u0105c wykorzysta\u0107 ka\u017cd\u0105 permutacj\u0119 rozwoju WordPressa, o kt\u00f3rej wiem (w tym rozmawiaj\u0105c o tym z kilkoma r\u00f3wie\u015bnikami), aby spr\u00f3bowa\u0107 zrobi\u0107 to w najlepszy mo\u017cliwy spos\u00f3b.<\/p>\n<p>Jednak to si\u0119 nie dzia\u0142o. I wtedy natkn\u0105\u0142em si\u0119 na nast\u0119pn\u0105 stron\u0119 <a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/esc_sql\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Kodeksu<\/a> :<\/p>\n<blockquote>\n<p>W 99% przypadk\u00f3w mo\u017cna zamiast tego u\u017cy\u0107 $wpdb-&gt;prepare() i jest to zalecana metoda. Ta funkcja jest do u\u017cytku tylko w tych rzadkich przypadkach, w kt\u00f3rych nie mo\u017cna \u0142atwo u\u017cy\u0107 $wpdb-&gt;prepare(). Jednym z przyk\u0142ad\u00f3w jest przygotowanie tablicy do u\u017cycia w klauzuli IN.<\/p>\n<\/blockquote>\n<p>I to w\u0142a\u015bnie pr\u00f3bowa\u0142em zrobi\u0107: chcia\u0142em przeszuka\u0107 tabel\u0119 meta postu, w kt\u00f3rej warto\u015bci klucza meta by\u0142y zawarte w tablicy.<\/p>\n<p>Oto jak to wszystko wypracowa\u0142em.<\/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\">Najpierw<\/a> utworzy\u0142em tablic\u0119 do przechowywania r\u00f3\u017cnych metakluczy, o kt\u00f3rych wiem, \u017ce w ko\u0144cu b\u0119d\u0119 musia\u0142 zmapowa\u0107 (chocia\u017c warto\u015b\u0107 kluczy nie ma znaczenia dla cel\u00f3w tego postu):<\/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\">Nast\u0119pnie<\/a> przekonwertowa\u0142em je na ci\u0105g znak\u00f3w zgodny z MySQL. To prawda, nie jest to dane wej\u015bciowe u\u017cytkownika i jest u\u017cywane w\u00a0 klauzuli <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>, wi\u0119c nie mo\u017cna go u\u017cy\u0107 w instrukcji <strong>przygotowania :<\/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\">Na koniec<\/a> utworzy\u0142em zapytanie i pobra\u0142em wyniki:<\/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>I tak sko\u0144czy\u0142em prac\u0119 z tablicami, w\u0142a\u015bciwo\u015bci\u0105 class i konfiguracj\u0105 zapytania.<\/p>\n<p>Czy to najlepszy spos\u00f3b na prac\u0119 z zapytaniami WordPress z klauzulami IN? Nie jestem pewien, ale bior\u0105c pod uwag\u0119 moje do\u015bwiadczenie, to, co przeczyta\u0142em i jak to dzia\u0142a, jestem zadowolony z efektu ko\u0144cowego.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">\u0179r\u00f3d\u0142o nagrywania:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Praca z zapytaniami WordPress z klauzulami IN mo\u017ce by\u0107 trudna, zw\u0142aszcza je\u015bli masz do czynienia z metakluczami. Oto, co znalaz\u0142em w pracy.<\/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":[721,919,805,866],"tags":[1169],"class_list":["post-228930","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deweloper","category-inny","category-php-7","category-wordpress-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/228930","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/comments?post=228930"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/228930\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/166518"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=228930"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=228930"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=228930"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}