
🛠 Як додати одне довільне поле до багатьох постів у WordPress
Сайт на WordPress розрісся до сотень постів, і в кожному потрібно прописати нове довільне поле. Відкривати кожен пост вручну й натискати «Оновити», заняття на пів дня, не менше.
Особливо якщо ви допрацьовуєте тему або підключаєте SEO-плагін, якому для роботи потрібен однаковий ключ meta_key для всієї стрічки постів. Адмінка WordPress не має кнопки «застосувати до всіх», але дає два шляхи розв'язати це кодом.
Нижче, обидва способи з готовими сніпетами: швидкий (один SQL-запит на всю пачку) і простий (цикл за ID з нативною функцією add_post_meta). Обирайте під задачу.

💡 Швидкий огляд:
- Масово проставити одне й те саме довільне поле всім постам можна через
add_post_metaу циклі, 4 рядки коду. - Якщо постів сотні й важлива швидкість, один прямий INSERT у таблицю
wp_postmetaчерез кастомну функцію. - Обидва способи працюють через
functions.phpтеми або плагін Code Snippets. Зробіть бекап бази перед запуском будь-якого SQL.
Навіщо додавати одне поле до багатьох постів одразу
Довільні поля (custom fields, вони ж post meta) зберігають додаткову інформацію про запис: кількість переглядів, теги для внутрішньої фільтрації, прапорець «в обраному», ID пов'язаного продукту. Усе, що не вміщується в стандартні поля post_title і post_content.
Зазвичай поле додають точково: відкрили пост, знайшли блок «Довільні поля» в редакторі, вписали ключ-значення. Але коли поле має з'явитися в усіх 200 постів одразу, ручний метод відпадає.
Типові сценарії, де потрібна масовість:
- Підключили дочірню тему, а вона використовує
get_post_meta($post_id, 'featured_post', true)для позначення популярних записів. Без масового заповнення старі пости не потраплять у видачу. - SEO-аудит вимагав проставити
noindexпевному типу контенту через метаполе, а не через robots.txt. - Міграція з іншого рушія: дані зі старої CMS лягли в CSV, і їх потрібно залити в
wp_postmetaдля тисяч записів.
У WordPress немає штатної функції add_multiple_posts_meta. Але є два перевірені шляхи, обирайте за ситуацією.
Спосіб 1. Один SQL-запит для всіх постів
Найшвидший спосіб, прямий INSERT у таблицю wp_postmeta однією транзакцією. Замість 200 окремих запитів до бази ви робите один, і він відпрацьовує за мілісекунди.
Нижче, функція add_multiple_posts_meta, яка приймає масив ID постів і повторює сигнатуру нативної add_post_meta: ті самі параметри, той самий порядок.
Додайте код у functions.php дочірньої теми або через плагін Code Snippets. Функція сама перевіряє, чи існує вже таке поле в поста (якщо передано $unique = true), і відфільтровує невалідні ID.
1 if( !function_exists( 'add_multiple_posts_meta' ) ){ 2 function add_multiple_posts_meta( $post_ids, $meta_key, $meta_value, $unique = false ){ 3 4 // Якщо ключ або ID не задані — виходимо 5 if( !$meta_key || empty( $post_ids ) ){ 6 return false; 7 } 8 9 // Один пост — віддаємо нативній add_post_meta 10 if( is_numeric( $post_ids ) || ( is_array( $post_ids ) && count( $post_ids ) === 1 ) ){ 11 return add_post_meta( 12 is_array( $post_ids ) ? $post_ids[0] : $post_ids, 13 $meta_key, 14 $meta_value, 15 $unique 16 ); 17 } 18 19 global $wpdb; 20 21 // Відсіюємо невалідні ID та дублікати 22 $valid_post_ids = array_unique( 23 array_filter( $post_ids, function( $post_id ) use ( $wpdb, $meta_key, $unique ){ 24 return $post_id 25 && is_numeric( $post_id ) 26 && get_post_status( $post_id ) 27 && ( 28 ! $unique 29 || ! $wpdb->get_var( $wpdb->prepare( 30 "SELECT COUNT(*) FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s", 31 $post_id, 32 $meta_key 33 ) ) 34 ); 35 } ) 36 ); 37 38 if( ! count( $valid_post_ids ) ){ 39 return false; 40 } 41 42 // Санітизація 43 $meta_key = wp_unslash( $meta_key ); 44 $meta_value = sanitize_meta( $meta_key, wp_unslash( $meta_value ), 'post' ); 45 46 // Збираємо дані та форматні рядки для одного INSERT 47 $insert_data = []; 48 $insert_formats = []; 49 50 foreach( $valid_post_ids as $post_id ){ 51 array_push( $insert_data, $post_id, $meta_key, $meta_value ); 52 $insert_formats[] = '(%d, %s, %s)'; 53 } 54 55 $sql_string = "INSERT INTO $wpdb->postmeta (`post_id`, `meta_key`, `meta_value`) VALUES " 56 . implode( ', ', $insert_formats ); 57 58 // ... розпаковує масив в окремі аргументи для prepare 59 $sql_query = $wpdb->prepare( $sql_string, ...$insert_data ); 60 61 return $wpdb->query( $sql_query ); 62 } 63 }
Що тут відбувається порядково. Перевірка !function_exists, страховка від конфлікту: якщо інший плагін уже оголосив функцію з таким ім'ям, фатальної помилки не буде. Блок is_numeric($post_ids) віддає одиничний ID нативній add_post_meta, так одна й та сама функція працює і з одним постом, і з масивом. Фільтр array_filter відкидає ID чернеток, видалених записів і ті, для яких унікальне поле вже існує. Санітизація через wp_unslash і sanitize_meta обов'язкова: без неї серіалізовані дані та спецсимволи зламають запит.
*Важливий момент із ...$insert_data.* Оператор ... (splat) розгортає масив у плаский список аргументів. Без нього $wpdb->prepare отримає один аргумент-масив замість набору (%d, %s, %s), і запит впаде з помилкою кількості плейсхолдерів. PHP 5.6+ (WordPress вимагає щонайменше 7.0, тож сміливо).
Як використовувати
Передайте масив ID постів, ключ і значення звичайним викликом. Четвертий параметр, прапорець унікальності: true не додасть поле, якщо воно вже є в поста.
1 $post_ids = [ 1, 2, 3, 42, 108 ]; 2 $meta_key = 'featured_priority'; 3 $meta_value = 'high'; 4 $unique = false; // проставить усім, навіть якщо поле вже було 5 6 add_multiple_posts_meta( $post_ids, $meta_key, $meta_value, $unique );
Запускати такий виклик зручно через хук init (один раз, потім видалити) або через WP-CLI командою wp eval-file. Після виконання обов'язково приберіть код із functions.php, інакше функція спрацьовуватиме при кожному завантаженні сторінки.
Спосіб 2. Цикл за ID з add_post_meta
Якщо не хочете чіпати SQL напряму, використовуйте нативний add_post_meta у циклі. Код учетверо коротший і повністю спирається на ядро WordPress.
1 $post_ids = [ 1, 2, 3, 42, 108 ]; 2 $meta_key = 'featured_priority'; 3 $meta_value = 'high'; 4 $unique = false; 5 6 foreach( $post_ids as $post_id ){ 7 add_post_meta( $post_id, $meta_key, $meta_value, $unique ); 8 }
Цикл проходить по масиву і для кожного ID смикає add_post_meta. Функція сама перевіряє існування запису, унікальність ключа (якщо задано $unique = true) і коректність даних, жодної додаткової валідації не потрібно.
Продуктивність. На сотні постів різниця з SQL-запитом непомітна. Але якщо у вас 5 000 записів, кожен виклик add_post_meta породжує окремий INSERT, плюс внутрішні хуки (added_post_meta, update_post_meta_cache). На таких обсягах перший спосіб з одним запитом відпрацює в 10-20 разів швидше.
Для разових операцій із парою десятків постів беріть цикл, не ускладнюйте.
Порівняння підходів
Критерій | Спосіб 1 (один SQL) | Спосіб 2 (цикл add_post_meta) |
|---|---|---|
Швидкість на 5 000 постів | ~0,2 сек (1 запит) | ~3-6 сек (5 000 запитів) |
Складність коду | ~50 рядків з валідацією | 4 рядки |
Безпека | Потрібна ручна санітизація | add_post_meta робить усе сам |
Хуки WordPress | Не викликаються | added_post_meta, update_post_meta_cache |
Коли обирати | Масова міграція, імпорт із CSV | Разові правки, до сотні постів |
Універсальне правило: якщо постів менше ста й операція разова, цикл. Якщо йдеться про регулярну синхронізацію або міграцію тисяч записів, тільки прямий запит із підготовленою функцією.
⁉️🤔 Часті запитання
Чи можна проставити поле вибірково, тільки постам із певної рубрики?
Так. Отримайте ID постів через get_posts із параметром 'category' => ID_рубрики, а потім передайте масив у будь-який із двох способів вище. Для тисяч постів додайте 'numberposts' => -1 і 'fields' => 'ids', запит поверне тільки масив ID, без завантаження об'єктів.
Ось готовий приклад:
$post_ids = get_posts( [ 'category' => 5, 'numberposts' => -1, 'fields' => 'ids', 'post_type' => 'post' ] );. Далі, викликadd_multiple_posts_meta($post_ids, ...)або цикл ізadd_post_meta.
Що робити, якщо потрібне різне значення поля для різних постів?
Масова вставка тут не підійде. Формуйте асоціативний масив [ ID_поста => значение ] і проходьте по ньому в циклі з add_post_meta або update_post_meta. Одне значення для всіх, SQL, різні для різних, тільки цикл.
Для 50+ постів з унікальними значеннями використовуйте
update_post_metaзамістьadd_post_meta: він не плодить дублікати, якщо поле вже існує.
Чи безпечно писати SQL-запити напряму в wp_postmeta?
Безпечно за двох умов. Перше: завжди проганяйте дані через $wpdb->prepare, він екранує спецсимволи та блокує SQL-ін'єкції. Друге: зробіть повний бекап бази перед запуском. Один невірний UPDATE без WHERE, і wp_postmeta очищена для всіх записів.
Команда для бекапу через WP-CLI:
wp db export backup-before-meta.sql. Відновити:wp db import backup-before-meta.sql.
Чим add_post_meta відрізняється від update_post_meta?
add_post_meta додає новий рядок у wp_postmeta, навіть якщо ключ уже є в поста, вийде дублікат. update_post_meta перевіряє існування ключа: якщо є, оновлює значення, якщо немає, створює. Для масового заповнення, де ключ один на пост, add_post_meta із $unique = true дає той самий ефект.
На практиці:
add_post_meta($id, 'views', 0, true)один раз створить поле і більше не чіпатиме.update_post_meta($id, 'views', $count)перезапише значення при кожному виклику.
Де розміщувати код, у темі чи плагіні?
Для разових операцій, у functions.php дочірньої теми, з негайним видаленням після виконання. Для повторюваних задач, оформіть як Must-Use плагін (папка wp-content/mu-plugins/) або додайте в Code Snippets із позначкою «Run once». Код в активній темі без видалення смикатиме базу при кожному завантаженні сторінки — це зайве навантаження.
Що взяти під вашу задачу
Практика показує: 9 із 10 випадків закриваються циклом із add_post_meta. Це чотири рядки коду, нативна функція і жодних сюрпризів.
Прямий SQL-запит виправданий у двох ситуаціях: масова міграція (тисячі постів, час дорогий) і періодична синхронізація, де ви контролюєте санітизацію на вході. В іншому, не ускладнюйте.
Що робити прямо зараз:
- Якщо потрібно проставити поле ≤100 постам, скопіюйте цикл із другого способу, підставте свої ID і запустіть.
- Якщо постів кілька тисяч, візьміть функцію з першого способу, але спершу протестуйте на копії сайту.
- У будь-якому варіанті, бекап бази перед запуском. Це не пересторога, а правило.
А яким способом ви зазвичай додаєте довільні поля: через адмінку, код чи плагін на кшталт ACF? Напишіть у коментарях, цікаво порівняти підходи.

![🛠 Як додати свій шорткод у WordPress: розбір add_shortcode() [+2 приклади]](/api/media/file/ai-cover-1785346567950.avif)
