WordPress图片URL主要存储在wp_posts表的post_content字段中,用于文章、页面等正文内的<img>标签src属性;其他如缩略图ID(_thumbnail_id)或上传路径(_wp_attached_file)均不直接存储URL。
WordPress数据库里图片URL存在哪几张表
wordpress的图片链接主要藏在 wp_posts 表的 post_content 字段里——文章正文、页面内容、自定义字段(如果用的是默认方式)里的 <img> 标签 src 都在这儿。部分主题或插件可能把缩略图 id 存在 wp_postmeta 的 _thumbnail_id,但那是 id 不是 url,不涉及字符串替换。
别碰 wp_options 里的 siteurl 或 home,那是站点地址,和图片链接无关;也别动 wp_postmeta 里带 _wp_attached_file 的记录,那是上传路径,不是前端显示的 URL。
所以核心就一张表:wp_posts,目标字段:post_content。
UPDATE语句怎么写才安全不翻车
直接 UPDATE wp_posts SET post_content = REPLACE(post_content, 'http://old.com/wp-content/uploads/', 'https://new.com/wp-content/uploads/') 看似简单,但有三个硬坑:
- 没加
WHERE post_content LIKE '%old.com%'—— 全表扫,慢且没必要,还可能误改空内容行 - 没转义斜杠或特殊字符 —— MySQL 的
REPLACE()不处理正则,但如果你旧 URL 里有单引号、反斜杠,得先确认是否被正确存储(通常不会,但迁移后乱码时可能出现) - 没备份 —— 这条语句不可逆,执行前必须导出
wp_posts表(至少是post_content列)
推荐写法:
UPDATE wp_posts SET post_content = REPLACE(post_content, 'http://old.com/wp-content/uploads/', 'https://new.com/wp-content/uploads/') WHERE post_content LIKE '%http://old.com/wp-content/uploads/%';
注意:协议(http vs https)、子目录(比如 /blog/)、结尾斜杠都要完全匹配,否则漏换或错换。
为什么不能只换域名,还得考虑相对路径和CDN
有些老站用的是相对路径,比如 src="/wp-content/uploads/2023/01/photo.jpg",这种不会被上面的语句捕获;还有些用了 CDN,实际存的是 src="https://cdn.old.com/...",那就要额外补一条 REPLACE。
更麻烦的是混用情况:同一站点里可能同时存在绝对路径、协议相对路径(//old.com/...)、甚至带端口的(http://old.com:8080/...)。这时候一条 SQL 不够,得按需分批跑:
REPLACE(..., 'http://old.com:', 'https://new.com:')REPLACE(..., '//old.com/', '//new.com/')-
REPLACE(..., '/wp-content/uploads/', '/wp-content/uploads/')(仅当目录结构也变了)
每次只改一种模式,改完查 SELECT COUNT(*) FROM wp_posts WHERE post_content LIKE '%old.com%' 确认清零再进行下一步。
执行后图片还是404?检查这几个地方
SQL 替换只是改了数据库里的 HTML 字符串,不代表文件真搬过去了。常见脱节点:
- 服务器上
/wp-content/uploads/目录没同步 —— 新域名下请求的图片物理路径不存在 - 对象存储(如 OSS、S3)没配置回源或没同步文件 —— 数据库换了,但云上还是旧文件
- 缓存没清:浏览器缓存、CDN 缓存、WordPress 插件缓存(如 WP Super Cache)都可能返回旧 HTML
- 某些页面由 JS 动态插入图片(比如图集插件),
post_content里根本没 src,得另查 JS 模板或 API 返回值
最稳的验证方式:找一篇刚改过的文章,在数据库里 SELECT post_content FROM wp_posts WHERE ID = 123,复制出来搜一下新 URL,确认存在;再用 Incognito 模式打开页面,禁用缓存,看 Network 面板里图片请求是不是 200。
真正麻烦的从来不是 SQL 语句本身,而是旧链接到底以多少种形式埋在了多少个地方——数据库只是第一关。










