Трохи більше року тому я написав допис про те, як використовувати WP_Meta_Query, коли у вас є набір ключів, які ви хочете використати, щоб допомогти отримати інформацію з бази даних.
А як щодо випадку, коли у вас є кілька різних ключів, які призведуть до створення дійсно довгого масиву для класу WP_Meta_Query? Наприклад, що, якби вам довелося переглянути колекцію даних ще до того, як налаштувати запит?
На певному рівні може здатися, що природною справою було б:
- перебирати колекцію ключів,
- динамічно нарощувати результати,
- об’єднати їх в один набір результатів,
- потім працюйте з тим, що вам дадуть.
Але хіба це не звучить трохи громіздко (не кажучи вже про повільне)?
Коли справа доходить до використання API WordPress, я роблю все можливе, щоб дотримуватися його, перш ніж спілкуватися, скажімо, безпосередньо з базою даних, але бувають випадки, коли має сенс написати необроблений запит, ніж просто написати якийсь розумний код щоб API WordPress працював.
Перш ніж перейти до обґрунтування того, чому я зробив те, що зробив, я хочу пояснити проблему та підхід. Ймовірно, це вбереже когось від передчасного кидання коментарів.
Цей знімок екрана не має нічого спільного із запитом. Просто знімок IDE для розваги.
Отже, ось:
- У мене є стандартний масив значень, які зрештою використовуються, щоб допомогти взяти метадані та створити з них власний тип публікації (оскільки їх було імпортовано зі стороннього джерела).
- Я великий прихильник параметризації запитів (і, отже, використання preparat ), щоб переконатися, що дані правильно запитуються до бази даних. На жаль, цього не сталося під час спроби виконати цей запит. Пізніше в цій публікації я поясню чому.
- Таким чином, перетворення масиву на рядок є корисним, але це все ще не вирішує проблему, чому стандартна функція підготовки не працює.
З огляду на це я збираюся пояснити кілька речей:
- чому я вирішив використовувати масив для зберігання значень метаданих,
- чому я використовував implode, щоб перетворити їх на рядок,
- чому я не використовую підготовку для обробки запиту.
Про значення метаданих
Причина збереження метаданих у масиві як властивості класу полягає в тому, що цей масив може змінюватися з часом.
Тобто нам може знадобитися імпортувати додаткові дані третіх сторін, видаляти дані третіх сторін або внести певні зміни в наявні дані.
Коли ці дані зберігаються в одному місці, це значно полегшує керування майбутніми версіями коду.
Знищення масиву
Щоразу, коли ви виконуєте запит до бази даних і вам потрібно працювати з масивом даних, ви можете використовувати WP_Meta_Query та використовувати кожен ключ як частину масиву аргументів.
Але якщо у вас є відносно великий набір даних, то спочатку потрібно прокрутити їх усе, потім створити запит, а потім обробити його.
І коли ви все це зробили, я не переконаний, що написаний код не стався за рахунок продуктивності. Ось чому іноді я вирішую використовувати wpdb.
Не використовується Prepare
Тепер, під час безпосереднього взаємодії з базою даних, я намагаюся переконатися:
- У мене для цього вагома причина,
- Я використовую параметризовані запити.
Але я деякий час працював із цим конкретним набором даних, намагаючись використати кожну перестановку розробки WordPress, про яку я знаю (зокрема, розмовляв про це з кількома колегами), щоб спробувати зробити цю роботу найкращим чином.
Однак цього не відбувалося. І саме тоді я натрапив на таку сторінку в Кодексі :
У 99% випадків замість цього можна використовувати $wpdb->prepare(), і це рекомендований метод. Ця функція призначена лише для тих рідкісних випадків, коли ви не можете легко використати $wpdb->prepare(). Одним із прикладів є підготовка масиву для використання в пропозиції IN.
І це саме те, що я намагався зробити: я шукав мета-таблицю публікацій, де значення мета-ключів містилися в масиві.
Отже, ось як я все це розробив.
По- перше, я створив масив для зберігання різних мета-ключів, які, як я знаю, зрештою потрібно буде відобразити (хоча значення ключів не має значення для цілей цієї публікації):
<?php
// This is used to maintain a map of data should we need to add more.
$data_types = [
'data_item_one',
'data_item_two',
'...'
'data_item_ten,
];
Потім я перетворив їх на готовий для MySQL рядок. Звичайно, це не введення користувача, і воно використовується в пропозиції IN, тому його не можна використовувати в операторі підготовки :
<?php
/**
* Converts the incoming array into a comma-delimited string with
* quotes wrapped around each key.
*
* @access private
*
* @param array $arr The array to convert to a string.
* @return string The string representation of the array delimited by quotes and commas.
*/
private function convert_to_sql_ready_string( $arr) {
return '"'. implode( $arr, '","' ). '"';
}
Нарешті я створив запит і отримав результати:
<?php
public function get_data_values() {
global $wpdb;
$query = "
SELECT post_id, meta_key, meta_value
FROM $wpdb->postmeta WHERE
meta_key in ($this->data_types) AND
meta_value <> '';
";
$results = $wpdb->get_results( $query );
return $results;
}
І ось як я завершив роботу з масивами, властивістю класу та налаштуванням свого запиту.
Це найкращий спосіб роботи із запитами WordPress із пропозиціями IN? Я не впевнений, але враховуючи мій досвід, те, що я прочитав і як це працює, я задоволений кінцевим результатом.