搜索全站
数据库 7 分钟阅读

WordPress 多站点共享媒体库与站间内容复制的实现方法

多站点默认每个子站有独立的 uploads 目录,图片无法共享。本文讲清三种解决方案:网络媒体库插件、统一 uploads 路径的钩子实现、以及站间内容复制的可行方式(含 WP-CLI 导出导入与数据库级复制),并分析各自的适用场景与风险。

U
UFO_PF 2023-07-16 · 阅读 7 分钟
Wo 数据库
阅读提示
本文约 2,449 字,预计阅读 7 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:多站点的”信息孤岛”问题

开了多站点后最常被问到的问题:主站上传的 logo、产品图,子站为什么用不了?

因为多站点的媒体库是按站点隔离的:

wp-content/uploads/          主站(ID=1)
wp-content/uploads/sites/2/  子站 2
wp-content/uploads/sites/3/  子站 3

数据库里 wp_2_posts 的附件记录也只属于子站 2。想跨站复用,要么改机制,要么走复制。

原理分析:为什么默认是隔离的

这个设计是有道理的:多站点常用于托管互不相关的站点(客户 A、客户 B),如果媒体库共享,等于把 A 的图片暴露给 B,既混乱也有隐私风险。

所以”共享”并非普适需求,只有当你管理的是同一体系下的多个站点(分站、多语言站、多品牌但共用素材库)时才有意义。

保姆级实操:三种方案

方案一:装网络媒体库插件(最省事)

典型插件:Network Shared Media、Multisite Shared Media。

以 Network Shared Media 为例:

  1. 网络管理 → 插件 → 网络启用;
  2. 任意子站媒体库会出现 “Shared Media” 标签;
  3. 上传到此处的图片会被所有子站引用,实际物理文件存于主站 uploads。

优点:配置简单、有界面。缺点:多一个插件依赖,且部分主题/构建器在取图时兼容性一般。

方案二:用钩子把子站 uploads 指向同一目录(代码方案)

在 wp-content/mu-plugins/shared-uploads.php:

<?php
/**
 * Plugin Name: 共享 uploads 目录
 * Description: 让所有子站共用主站的上传目录
 */

add_filter('upload_dir', function ($uploads) {
    if (is_main_site()) {
        return $uploads;
    }

    // 取主站上传目录
    switch_to_blog(1);
    $main = wp_upload_dir();
    restore_current_blog();

    $uploads['basedir'] = $main['basedir'];
    $uploads['baseurl'] = $main['baseurl'];
    $uploads['path']    = $main['path'];
    $uploads['url']     = $main['url'];
    $uploads['subdir']  = $main['subdir'];

    return $uploads;
});

放在 mu-plugins 下会自动对所有站点生效,后台无法停用。

风险提示:所有子站写同一个目录,文件名冲突靠 WordPress 自动加后缀处理,但删除操作是全局的——子站 A 删图片,子站 B 引用同一文件的文章会变成坏图。适合素材只读共享的场景。

方案三:站间内容复制

如果目标是把主站的 50 篇文章复制到子站,而不是共享文件:

  • WP-CLI 导出导入:主站 wp export,子站 wp import(导入器需按站点启用)。
wp export --dir=/tmp/exp --post_type=post --status=publish
wp --url=shanghai.mimangfei.com plugin install wordpress-importer --activate
wp --url=shanghai.mimangfei.com import /tmp/exp/site.xml --authors=create
  • 数据库级复制(更快,但风险高):把 wp_posts、wp_postmeta 里 post_type 为 post 的记录复制成 wp_2_posts 的前缀。需要同步处理分类、标签、附件关联,不推荐手工做,建议用插件(如 Multisite Content Copier / NS Cloner)。

方案四:复制单个站点作为模板

NS Cloner 插件可以”克隆一个现有站点为新子站”,适合连锁分站这种结构高度相似的场景。

常见踩坑与失败案例

  1. 共享 uploads 后子站媒体库显示空 —— 数据库里的附件记录仍属于主站,子站媒体库只列自己的记录。代码方案解决的是”上传位置”,不解决”已有记录”,需要用插件或 SQL 同步 wp_posts 中 post_type=attachment 的记录。
  2. 案例:某连锁品牌用代码方案共享 uploads,子站编辑误删一张共用产品图,导致 12 个子站的产品页全部出现裂图。共享目录 + 只读素材是唯一安全的组合,日常可变的图片不要共享。
  3. 导入后图片仍指向主站域名 —— 子域名模式下要 wp --url=子站 search-replace 'https://主站/uploads' 'https://共享路径/uploads'。
  4. 网络启用插件后子站无法单独停用 —— 这是多站点设计,需要在网络后台操作。
  5. switch_to_blog 嵌套调用 —— 在钩子中调用要注意不要重复切换,否则 restore_current_blog 层级错乱,可用全局变量记录状态。

总结

共享媒体库有三种层次:文件级共享(mu-plugins 钩子,最轻但有删除风险)、记录级共享(插件,最实用)、内容复制(WP-CLI 或克隆插件,适合批量建站)。我推荐的做法是:共用素材(品牌图、图标、证书)放共享目录并设为只读;各站专属内容各存各的。这样既省了重复上传,又不会一处删除处处裂图。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。