<? phpukraine СПІВБЕСІДИ
Пошук по платформі
WORDPRESS · SENIOR

Коли доречний WordPress Multisite і які в нього обмеження?

Multisite виправданий, коли багато однотипних сайтів живуть на одному коді, одній базі й під одною командою; він дає спільні wp_users і спільний набір плагінів, але й спільну долю - оновлення, падіння, бекап і безпека стають мережевими, а не посайтовими.

У нас 40 сайтів міських філій на однаковому дизайні. Multisite чи 40 інсталяцій?
Чому користувач із роллю адміністратора на сайті мережі не бачить пункт «Плагіни»?
Клієнт просить віддати йому його сайт із мережі окремо. Як ви це зробите?
Що станеться з мережею, якщо network-activated плагін впаде з fatal error?
multisite мережа switch_to_blog домени адміністрування

Multisite - це той самий WordPress, у якому константа MULTISITE = true вмикає вибір префікса таблиць за поточним доменом і шляхом. Сайт з ID 2 працює з wp_2_posts і wp_2_options, сайт 3 - зі своїми. Спільними лишаються wp_users, wp_usermeta й мережевий шар: wp_blogs зі списком сайтів, wp_sitemeta з налаштуваннями мережі, wp_blogmeta (зʼявилась у WP 5.0). Акаунт при цьому один, а контент роздільний: той самий редактор може мати роль на трьох сайтах і не мати доступу до четвертого, бо приналежність визначає ключ wp_{id}_capabilities в usermeta.

Плагіни й теми в мережі одні фізично. Каталог wp-content/plugins спільний, і покласти туди щось може лише super admin: у Multisite map_meta_cap знімає install_plugins, edit_plugins і update_themes навіть з адміністратора сайту. Режимів активації два - network activate вмикає плагін одразу всюди, звичайна активація діє на конкретному сайті, а is_plugin_active_for_network() дозволяє коду відрізнити ці випадки. Тема стає доступною сайту лише після network enable. Заради цього мережі здебільшого й будують: 40 сайтів обласних філій оновлюються одним wp plugin update --all, а не сорока.

Тип доменів обирають один раз. SUBDOMAIN_INSTALL фіксується під час Network Setup: піддомени вимагають wildcard у DNS, у vhost і в сертифікаті, підтеки не вимагають нічого, зате конфліктують зі слагами вже наявних сторінок. Змінити тип пізніше означає правку констант плюс масовий апдейт domain і path у wp_blogs з редиректами, тобто повноцінну міграцію. Власні домени ядро підтримує з WP 4.5 без сторонніх плагінів: у wp_blogs.domain пишеться будь-який домен, і мережа на нього відповідає; sunrise.php лишився для нестандартної логіки резолву. Наскрізний логін діє в межах одного COOKIE_DOMAIN, тож для мережі з різних доменів SSO доводиться робити окремо.

Зворотний бік мережі - спільна доля. Версія ядра одна на всіх, оновлення плагіна прилітає всім одночасно, fatal error у network-activated плагіні гасить усі сайти. RCE на одному сайті відкриває файлову систему й базу цілої мережі, тому «розділимо клієнтів по сайтах заради ізоляції» - хибна ідея. Бекап знімається цілою базою, а витягнути один сайт означає вибрати його таблиці через wp db tables --url=..., забрати wp-content/uploads/sites/{id} і розібратися зі спільною wp_users. Масштаб додає своє: кожен сайт це близько 12 таблиць, тисяча сайтів - десятки тисяч файлів на диску й повільні дампи, а wp_is_large_network() від 10 000 сайтів або користувачів вимикає підрахунок статистики на льоту.

Multisite виправданий, коли сайти однакові за стеком, належать одному власнику, обслуговуються однією командою й ділять реліз-цикл: мовні версії корпоративного сайту, кафедри університету, міські лендінги франшизи, site-per-customer у продукті, де кодом керуєте ви самі. Окремі інсталяції кращі, коли клієнт може забрати свій сайт, коли комусь потрібні свої плагіни або заморожена версія, коли трафік асиметричний і масштабувати треба один сайт, коли є вимога ізолювати дані. А якщо єдиний аргумент за мережу - спільний логін, дешевше поставити SSO над окремими сайтами, ніж звʼязати їх однією базою назавжди.

// Мережеві налаштування живуть у wp_sitemeta, а не в опціях сайту
update_site_option('acme_license_key', $key);      // одна на всю мережу
$key = get_site_option('acme_license_key');
update_option('acme_theme_accent', '#0a5');        // тільки поточний сайт

// Новий сайт у мережі: хук wp_initialize_site (WP 5.1+), не wpmu_new_blog
add_action('wp_initialize_site', function (WP_Site $site): void {
    switch_to_blog((int) $site->blog_id);
    acme_install_tables();      // dbDelta для таблиць саме цього сайту
    restore_current_blog();
}, 20);

// Збір даних по мережі: get_sites(), а не прямий SELECT з wp_blogs
$latest = [];
foreach (get_sites(['number' => 100, 'archived' => 0, 'deleted' => 0]) as $site) {
    switch_to_blog((int) $site->blog_id);
    // кожен switch скидає кеш опцій і додає запити,
    // тому такий цикл місце має в cron, а не в рендері сторінки
    $latest[$site->blog_id] = get_posts(['numberposts' => 3, 'fields' => 'ids']);
    restore_current_blog();      // парність обовʼязкова, інакше $wpdb лишиться чужим
}
set_site_transient('acme_network_latest', $latest, HOUR_IN_SECONDS);

// Права після switch_to_blog самі не перемикаються
$user = wp_get_current_user();
$canEditOnSite5 = $user->for_site(5)->has_cap('edit_posts');  // WP 4.9+
$user->for_site(get_current_blog_id());                       // повертаємо контекст
Що спільними є лише wp_users, wp_usermeta й мережеві таблиці (wp_blogs, wp_sitemeta, wp_blogmeta), а контент кожного сайту лежить у власному наборі таблиць з префіксом wp_2_, wp_3_ і т.д.
Що плагіни й теми фізично одні на всю мережу: встановити їх може лише super admin, а адміністратор окремого сайту не має install_plugins і edit_themes.
Що вибір subdomain/subdirectory фіксується константою SUBDOMAIN_INSTALL на етапі Network Setup, а власні домени підтримуються ядром з WP 4.5 через поле domain у wp_blogs, без плагіна domain mapping.
Що switch_to_blog() перемикає префікс $wpdb і кеші, але не перевибирає capabilities вже завантаженого WP_User: для перевірки прав на іншому сайті потрібен $user->for_site($id).
Що окремі інсталяції кращі, коли сайтам потрібні різні версії WP, різні релізні цикли, ізоляція компрометації або віддача сайту клієнту, і що спільний логін можна отримати через SSO, не будуючи мережу.
Вважати, що Multisite шарить контент: пости, категорії та медіа за замовчуванням ізольовані, спільний лише список користувачів.
Обіцяти клієнту «просто винесемо його сайт з мережі потім» - експорт означає вибірку wp_7_* таблиць, переписування uploads/sites/7 і розбір спільної wp_users.
Плутати update_option і update_site_option: перша пише в опції поточного сайту, друга в wp_sitemeta на всю мережу.
Робити switch_to_blog() у циклі по тисячі сайтів у запиті фронтенду замість фонової задачі з кешуванням у site transient.
Забувати restore_current_blog() або викликати його не парно, через що далі по коду $wpdb пише не в ту базу таблиць.
Планувати Multisite заради ізоляції безпеки: RCE в одному плагіні дає доступ до всієї файлової системи й усієї бази мережі.
ПОРАДА

Сформулюйте критерій одним реченням: Multisite - це один деплой, одна база й один власник. Щойно комусь із сайтів потрібен свій реліз-цикл, свій набір плагінів або своя відповідальність за дані, вигода мережі зникає, а вартість лишається.

оновлено 8 вересня 2026 · ліцензія CC-BY-SA-4.0 Знайшли неточність? Напишіть →
ПЕРЕВІРТЕ СЕБЕ

Мережа шарить облікові записи й мережеві налаштування; контент ізольований по таблицях, а код і версія WordPress одні на всіх.