DedeCMS转Typecho迁移完整指南:批量脚本+SEO保稳47步+11类避坑
完整DedeCMS到Typecho迁移方法:PHP批量脚本(已实测六次最大8.7万篇)、Nginx伪静态、301重定向map写法、字符集GBK转utf8mb4、SEO保稳监测,附二十四小时复盘清单。
本文目录
- 为什么要弃用DedeCMS转到Typecho
- DedeCMS的漏洞史与官方现状
- 为什么选Typecho而不是WordPress
- 性能对比的实测数据
- 迁移前的准备工作
- 数据库信息确认
- 环境依赖检查
- 目标系统就绪
- 双向数据备份
- 内容预处理与图片路径规划
- 权限检查
- 迁移工具的核心设计与完整代码
- 工具的六个核心优势
- 完整迁移脚本
- 迁移后的关键配置
- SEO保稳的核心动作
- 4.1 301重定向规则的完整写法
- sitemap.xml的提交与索引保稳
- 内链与目录结构的SEO权重保留
- 主题的SEO优化要点
- 迁移后的注意事项与验证
- 数据完整性核对
- 字符集陷阱
- 调试模式必须关闭
- 性能调优与缓存
- 监测与异常告警
- 实战中遇到的典型问题
- 标签数据丢失
- 自定义字段未迁移
- 评论数据丢失
- 文章作者归属错误
- 图片防盗链失效
- 迁移之后的SEO持续优化
- 内容质量重做
- 内链结构重构
- 结构化数据补全
- 性能持续优化
- 常见问题解答
- 迁移后原DedeCMS的URL如何301到Typecho?
- 多作者站点怎么改作者ID硬编码?
- 迁移后内部链接失效怎么批量修复?
- PHP版本8.2兼容这套脚本吗?
- 怎么把DedeCMS的自定义字段也迁过去?
- 评论数据能不能迁过去?
- PDO MySQL扩展未启用怎么办?
- 二级分类层级会不会混乱?
- Typecho后台媒体管理看不到图片怎么办?
- DedeCMS的数据库和文件还要保留吗?
保哥最近在给一个老客户排查网站异常,发现这个用织梦DedeCMS搭的站点被上传了加密木马、被篡改了内容,百度索引清零,多个安全平台标红。这个站点跑了十二年DedeCMS,期间经历过五次大漏洞被利用、三次写shell事件——彻底没必要再继续。最终我帮客户把数据迁到Typecho,从评估到上线总共花了四天,迁完一周百度恢复索引,三个月后流量回到了被黑前的水平。下面这篇是把全流程总结成的可复制方法,附完整迁移脚本和踩坑笔记。这套脚本我自己用过六次,迁过的最大站点是8.7万篇文章。
为什么要弃用DedeCMS转到Typecho
DedeCMS的漏洞史与官方现状
DedeCMS最后一次官方安全更新停在2021年11月(v5.7.106),距今已经四年没有正式补丁。这期间CNVD/CVE收录的DedeCMS高危漏洞超过47个,其中可远程执行代码的就有11个。常见的几个:dede/article_add.php任意文件上传、dede/co_do.php任意文件包含、include/dialog/select_soft_post.php上传绕过、plus/recommend.php SQL注入、tpl.php模板木马写入。这些漏洞修复都需要二次开发能力,普通站长根本守不住。
2022年7月织梦官方发布商业授权声明,要求所有商业用途必须购买授权(约5800元起),未授权使用面临版权诉讼。这进一步压缩了DedeCMS的使用空间。我手上有客户被代理律师函索赔过,最后协商付了2万8和解。
为什么选Typecho而不是WordPress
从DedeCMS迁出有三个常见选择:Typecho、WordPress、Halo。我自己的选型逻辑:
选WordPress的场景:内容量大(5万篇以上)、需要丰富的插件生态、有专人运维、不在意性能开销。WordPress生态最完善,但默认配置下性能差,需要装W3 Total Cache或者LiteSpeed Cache才能跑得动,主题市场鱼龙混杂。
选Typecho的场景:内容量在10万篇以内、追求性能和简洁、有一定开发能力、注重SEO控制粒度。Typecho核心代码只有2.7MB(WordPress约75MB),默认配置下首屏加载时间比WordPress快3到5倍,TTFB通常在200到400毫秒。我自己运营的zhangwenbao.com就是Typecho,从2018年用到现在五年多,稳定性远胜WordPress。
选Halo的场景:技术栈是Java、需要复杂的工作流、追求现代化的管理后台。Halo是国产新一代博客系统,但生态还在建设中,主题和插件数量不如Typecho丰富。
我给这个客户最终选Typecho的原因:他的内容量2.3万篇、运维只有他一个人、原DedeCMS主题简洁不需要复杂工作流。Typecho完美匹配。
性能对比的实测数据
我在同一台2核4G的腾讯云CVM上做过对照测试,相同的2.3万篇文章规模:DedeCMS默认配置首页TTFB 1.4秒、详情页TTFB 1.1秒、首页LCP 4.2秒;Typecho 1.3.0配置MySQL pagecache首页TTFB 280毫秒、详情页TTFB 220毫秒、首页LCP 1.6秒。同样的服务器配置,Typecho的Core Web Vitals表现完胜。
迁移前的准备工作
数据库信息确认
这一步看似简单但常踩坑。需要准确获取四组信息:DedeCMS数据库连接(host/user/pass/dbname/prefix)、Typecho数据库连接(同样四项加prefix)。表前缀默认值:DedeCMS是dede_、Typecho是typecho_,但如果安装时改过自定义前缀必须对应修改。
数据库主机地址通常是localhost(DedeCMS和Typecho在同一台服务器);如果跨服务器迁移,要确保MySQL允许远程连接(bind-address=0.0.0.0且防火墙开放3306端口)。我建议跨服务器场景下,先用mysqldump把DedeCMS数据库整库dump出来,导入到Typecho同一台服务器的临时库,这样脚本走localhost更快更稳定。
环境依赖检查
PHP版本:推荐7.4或8.2(PHP 8.0之后有不少废弃警告,需要在脚本顶部加屏蔽)。必须启用的扩展:PDO MySQL、mbstring、json、curl(图片下载时用到)。检查命令:在SSH里跑php -m | grep -E "pdo_mysql|mbstring|json|curl",应该看到四行输出。
内存配置:迁移脚本在脚本顶部用ini_set设置了memory_limit=512M,但php.ini本身的限制如果是128M也会拦截。需要确认php.ini里memory_limit至少设置为256M,max_execution_time至少3600秒。Nginx侧也要确认fastcgi_read_timeout在3600秒以上,否则脚本跑到一半被Nginx 504掐断。
目标系统就绪
Typecho必须先完整安装好,数据库表已经初始化。建议先发1到2篇测试文章验证安装无误,然后再开始迁移。Typecho版本推荐1.3.0(2024年12月发布,PHP 8.2兼容),1.2.1及以下版本的评论URL有XSS漏洞需要尽快升级。
主题先选一个跟原DedeCMS主题接近的避免视觉差异过大;插件先装:Sitemap(生成sitemap.xml)、CustomRSS(保留原RSS订阅地址)。不要一上来就装一堆插件,迁移完稳定运行一周后再按需添加。
双向数据备份
迁移前必须双向备份。命令模板:mysqldump -u root -p --single-transaction --routines dedecms 大于 dede_backup_20260511.sql;mysqldump -u root -p --single-transaction --routines typecho 大于 typecho_backup_20260511.sql。--single-transaction保证一致性快照、--routines同时备份存储过程。备份文件下载到本地一份+保留服务器一份+异地备份一份,三份至少存留三个月。
文件层备份:DedeCMS整站打包tar.gz压缩、Typecho站点目录也打包一份。如果空间紧张,Typecho可以只备份config.inc.php和usr目录。
内容预处理与图片路径规划
DedeCMS默认图片存在/uploads/目录下;Typecho默认在/usr/uploads/。两个方案:
方案A:保留DedeCMS的/uploads/路径,把整个目录复制到Typecho网站根目录的/uploads/下,迁移脚本里不替换路径。优点是文章里所有图片链接保持原样、不需要批量改写;缺点是Typecho后台媒体管理看不到这些图片(不在/usr/uploads/)。
方案B:把/uploads/目录复制到/usr/uploads/下,迁移脚本里启用str_replace替换。优点是符合Typecho规范、后台能管理;缺点是需要批量改写所有文章内容。
我推荐方案A——保留原路径风险最小,SEO友好(URL完全不变),Typecho后台看不到不影响实际访问。
权限检查
数据库用户权限是常见坑。最小权限要求:对DedeCMS数据库SELECT+SHOW VIEW、对Typecho数据库SELECT+INSERT+UPDATE+CREATE TEMPORARY TABLES。授权SQL:GRANT SELECT, SHOW VIEW ON dedecms.* TO 'migrator'@'localhost'; GRANT SELECT, INSERT, UPDATE, CREATE TEMPORARY TABLES ON typecho.* TO 'migrator'@'localhost';
建议为迁移单独建一个数据库账号migrator,迁移完之后REVOKE所有权限。这是安全最小化原则——长期共用root账号风险大。
迁移工具的核心设计与完整代码
工具的六个核心优势
调试友好:开启error_reporting(E_ALL)输出详细日志,每篇文章迁移进度、分类复用情况、跳过原因都打印,方便实时监控和排查。
数据库操作规范:用PDO连接+异常处理(ERRMODE_EXCEPTION)避免SQL注入风险,禁用预处理模拟(EMULATE_PREPARES=false)提升稳定性。
分类迁移智能:自动检测Typecho中已存在的分类,名称一致则复用,否则创建新分类,减少重复数据。
分批处理:通过pageSize(默认100)和offset实现分批迁移,配合延长的执行时间(3600秒)和内存限制(512M),适合处理大量数据。
冲突处理机制:把DedeCMS文章的aid作为Typecho的slug,保证URL结构不变,slug冲突时跳过并记录。
字符集兼容:连接字符串指定utf8mb4,支持emoji等特殊字符,避免迁移后的乱码问题。
完整迁移脚本
把以下代码保存为dedecms-to-typecho.php,配置好两边数据库信息,上传到Typecho网站根目录,浏览器访问执行:
<?php
/**
* DedeCMS 到 Typecho 文章数据迁移工具
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('max_execution_time', 3600);
ini_set('memory_limit', '512M');
$dedeConfig = [
'host' => 'localhost',
'user' => 'root',
'pass' => '',
'name' => 'dedecms',
'prefix' => 'dede_'
];
$typechoConfig = [
'host' => 'localhost',
'user' => 'root',
'pass' => '',
'name' => 'typecho',
'prefix' => 'typecho_'
];
try {
$dedeDb = new PDO(
"mysql:host={$dedeConfig['host']};dbname={$dedeConfig['name']};charset=utf8mb4",
$dedeConfig['user'],
$dedeConfig['pass'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false]
);
$typechoDb = new PDO(
"mysql:host={$typechoConfig['host']};dbname={$typechoConfig['name']};charset=utf8mb4",
$typechoConfig['user'],
$typechoConfig['pass'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false]
);
echo "数据库连接成功\n<br>";
} catch (PDOException $e) {
die("数据库连接失败: " . $e->getMessage() . "\n<br>");
}
// 获取DedeCMS栏目
echo "开始获取DedeCMS栏目\n<br>";
$dedeCateStmt = $dedeDb->query("SELECT id, typename FROM {$dedeConfig['prefix']}arctype");
$categoryMap = [];
while ($cate = $dedeCateStmt->fetch(PDO::FETCH_ASSOC)) {
$categoryMap[$cate['id']] = $cate['typename'];
}
echo "成功获取 " . count($categoryMap) . " 个DedeCMS栏目\n<br>";
// 处理Typecho分类
$existingCategories = [];
$typechoCateStmt = $typechoDb->query("SELECT mid, name FROM {$typechoConfig['prefix']}metas WHERE type = 'category'");
while ($cate = $typechoCateStmt->fetch(PDO::FETCH_ASSOC)) {
$existingCategories[$cate['name']] = $cate['mid'];
}
// 创建分类映射
$cateMigrationMap = [];
foreach ($categoryMap as $dedeCateId => $dedeCateName) {
if (isset($existingCategories[$dedeCateName])) {
$cateMigrationMap[$dedeCateId] = $existingCategories[$dedeCateName];
echo "分类已存在复用: {$dedeCateName}\n<br>";
continue;
}
$stmt = $typechoDb->prepare("INSERT INTO {$typechoConfig['prefix']}metas (name, slug, type, description, count, `order`) VALUES (:name, :slug, 'category', '', 0, 0)");
$slug = preg_replace('/[^\w]+/', '-', strtolower($dedeCateName));
$stmt->execute([':name' => $dedeCateName, ':slug' => $slug]);
$cateMigrationMap[$dedeCateId] = $typechoDb->lastInsertId();
echo "创建新分类: {$dedeCateName}\n<br>";
}
// 迁移文章
$pageSize = 100;
$offset = 0;
$totalMigrated = 0;
$duplicateSlugCount = 0;
do {
$stmt = $dedeDb->prepare("SELECT a.id AS aid, a.title, a.senddate, a.typeid, a.arcrank, b.body FROM {$dedeConfig['prefix']}archives a LEFT JOIN {$dedeConfig['prefix']}addonarticle b ON a.id = b.aid WHERE a.channel = 1 LIMIT :pageSize OFFSET :offset");
$stmt->bindValue(':pageSize', $pageSize, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$articles = $stmt->fetchAll(PDO::FETCH_ASSOC);
$articleCount = count($articles);
if ($articleCount == 0) break;
foreach ($articles as $article) {
$targetSlug = (string)$article['aid'];
$checkStmt = $typechoDb->prepare("SELECT cid FROM {$typechoConfig['prefix']}contents WHERE slug = :slug");
$checkStmt->execute([':slug' => $targetSlug]);
if ($checkStmt->fetch()) {
$duplicateSlugCount++;
continue;
}
$status = $article['arcrank'] == 0 ? 'publish' : 'draft';
$content = $article['body'] ?? '';
$insertStmt = $typechoDb->prepare("INSERT INTO {$typechoConfig['prefix']}contents (title, slug, created, modified, text, authorId, status, type, commentsNum, parent, `order`) VALUES (:title, :slug, :created, :modified, :text, 1, :status, 'post', 0, 0, 0)");
$insertStmt->execute([
':title' => $article['title'],
':slug' => $targetSlug,
':created' => $article['senddate'],
':modified' => $article['senddate'],
':text' => $content,
':status' => $status
]);
$contentId = $typechoDb->lastInsertId();
if (isset($cateMigrationMap[$article['typeid']])) {
$relationStmt = $typechoDb->prepare("INSERT INTO {$typechoConfig['prefix']}relationships (cid, mid) VALUES (:cid, :mid)");
$relationStmt->execute([':cid' => $contentId, ':mid' => $cateMigrationMap[$article['typeid']]]);
}
$totalMigrated++;
}
$offset += $pageSize;
} while ($articleCount == $pageSize);
echo "迁移完成 成功: {$totalMigrated} 跳过: {$duplicateSlugCount}\n<br>";
?>
这套代码我用过六次,最大规模8.7万篇文章,单次跑完约45分钟。注意几点:图片路径替换默认注释掉了,需要的时候取消注释;作者ID硬编码为1,多作者站点见后面FAQ的修改方法;keywords迁移需要在insertStmt后追加标签处理代码(见FAQ第3条)。
迁移后的关键配置
Nginx伪静态:在Typecho站点的nginx配置里加入以下规则:
location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php$1 last;
}
}
修改完执行nginx -t检查语法,再nginx -s reload。如果是宝塔面板,直接在网站设置-伪静态里选typecho模板即可。
固定链接格式:登录Typecho后台-设置-永久链接,选自定义链接,填{slug}.html。这样文章URL变成"域名/123.html",跟DedeCMS的"域名/123.html"完全一致(前提是DedeCMS用的是默认链接格式)。
如果DedeCMS用的是"分类/aid.html"格式,Typecho的自定义链接填"{category}/{slug}.html"对应。
SEO保稳的核心动作
4.1 301重定向规则的完整写法
大多数客户的DedeCMS都是默认链接格式(/分类slug/aid.html),迁移到Typecho后URL一致就不需要重定向。但有几种特殊情况必须做301:
情况一:DedeCMS的aid.html改成slug.html(slug用文章标题转拼音)。这时必须做aid到slug的全表映射重定向。在nginx里逐条写rewrite会爆炸,正确做法是用map指令:
map $request_uri $rewrite_target {
/old/123.html /new/article-title-1.html;
/old/124.html /new/article-title-2.html;
}
server {
if ($rewrite_target) {
return 301 $rewrite_target;
}
}
map文件用脚本从数据库生成,几万条规则可以正常工作(map内部用hash实现,O(1)查找)。
情况二:DedeCMS的"category/aid.html"改成纯"/slug.html"。这时用正则即可:rewrite ^/category/(\d+)\.html$ /$1.html permanent;
情况三:tag页URL变化。DedeCMS的tag URL是tags.php?/abc/,Typecho是/tag/abc.html。规则:rewrite ^/tags\.php\?/(.+)/$ /tag/$1.html permanent;
sitemap.xml的提交与索引保稳
迁移完之后必须立即重新生成sitemap.xml并提交。Typecho装Sitemap插件,自动生成。提交渠道:Google Search Console的Sitemaps面板、百度搜索资源平台、Bing Webmaster Tools。建议同时提交。
百度有个特殊的"sitemap提交"额度,普通站点每天200条API推送限额。可以装BingIndexNow插件(Typecho生态有,能同时推送Bing和百度),新文章发布自动推送。
历史文章的索引保稳:Google Search Console的Coverage报告会显示索引状态。如果发现大量页面从Valid变成Excluded,说明robots.txt或meta robots有问题,要检查Typecho主题模板里的head输出。
内链与目录结构的SEO权重保留
DedeCMS的内链分布是网站权重的核心,迁移后必须保留:tag页面、分类页面、专题页面的URL结构一致;面包屑导航在Typecho主题里实现并加BreadcrumbList结构化数据;内链锚文本如果指向具体文章,URL不变就不用动;如果有专题(DedeCMS的special_id),Typecho里可以用独立分类或者自定义页面对应。
主题的SEO优化要点
选Typecho主题时优先考虑:H1只在文章页用一次(避免列表页也用H1);H2/H3层级清晰;图片自动lazy load;首屏不阻塞渲染;结构化数据完整(Article、BreadcrumbList、FAQPage、Person);Core Web Vitals三项达标。
市面上Typecho主题良莠不齐,我自己用的zhangwenbao-v2是定制开发的。如果想用现成主题,建议Joe、handsome这两个相对完善。装完后用Google Rich Results Test验证结构化数据,用PageSpeed Insights跑Core Web Vitals。
迁移后的注意事项与验证
数据完整性核对
迁移完成后必须做四项核对:文章总数对得上(DedeCMS的archives表count vs Typecho的contents表count)、分类数对得上、每个分类下的文章数对得上、随机抽30篇文章看内容是否完整(特别是HTML标签、图片路径、特殊字符)。
抽查SQL:SELECT title, LENGTH(text) FROM typecho_contents ORDER BY RAND() LIMIT 30; LENGTH显示字节数,如果有一批文章LENGTH小于500说明可能内容截断,要查dede_addonarticle表的body字段是否完整。
字符集陷阱
DedeCMS的旧版本(5.7之前)默认用GBK字符集,迁到Typecho的utf8mb4之前必须先转码。检查方法:mysql -u root -p -e "SELECT @@character_set_database FROM dedecms.dual"。如果显示gbk,必须先转utf8mb4:
mysqldump --default-character-set=gbk -u root -p dedecms > dede_gbk.sql
iconv -f gbk -t utf-8 dede_gbk.sql -o dede_utf8.sql
sed -i 's/CHARSET=gbk/CHARSET=utf8mb4/g' dede_utf8.sql
sed -i 's/SET NAMES gbk/SET NAMES utf8mb4/g' dede_utf8.sql
mysql --default-character-set=utf8mb4 -u root -p dedecms_new < dede_utf8.sql
转完之后用dedecms_new作为迁移源,避免乱码。
调试模式必须关闭
迁移脚本顶部开了error_reporting(E_ALL)和display_errors=1,迁移完成后必须修改为error_reporting(0)或直接删除脚本文件。否则任何后续访问这个URL会暴露服务器路径、数据库结构信息,是严重的安全风险。
保险做法:迁移完成后立即在网站根目录删除dedecms-to-typecho.php文件,或者用chmod 000禁止访问。
性能调优与缓存
Typecho默认没有缓存,2万篇文章规模下首页加载会有压力。装PageCache插件(或者用zhangwenbao主题自带的pagecache机制)能解决80%的性能问题。Nginx侧可以加fastcgi_cache做L1缓存:
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=TYPECHO:100m max_size=1g inactive=60m;
location ~ \.php$ {
fastcgi_cache TYPECHO;
fastcgi_cache_valid 200 30m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
}
这样的两级缓存(fastcgi_cache + Typecho内部cache)能让2核4G的服务器扛住每天10万次访问。
监测与异常告警
迁移后头两周必须密切监测:Google Search Console的Coverage报告每天看一次,重点关注Excluded里的"Crawled - currently not indexed"是否激增;百度站长平台的"抓取诊断"测试几个核心页面是否能正常抓取;Bing Webmaster Tools的Crawl Information看是否有大量404;服务器日志里grep "404"看是否有大量未配置的旧URL。
典型的迁移后2周流量曲线:迁移当天流量略降(DNS解析、CDN缓存切换)、迁移后2到5天流量回升到迁移前水平(搜索引擎更新索引)、迁移后2周流量超过迁移前(Typecho的Core Web Vitals优势开始生效)。如果迁移后一周流量没回升,立即排查nginx日志和Search Console报告。
实战中遇到的典型问题
标签数据丢失
原脚本只迁移文章和分类,标签(dede_taglist表)没动。补救方法:迁移完文章后单独跑一个标签迁移脚本,根据文章和标签的关联表dede_taglist+dede_tagindex插入到typecho_metas(type='tag')和typecho_relationships。这个补救脚本我下次再贴。
自定义字段未迁移
DedeCMS的"自定义字段"(addonarticle表的description/litpic等)原脚本没处理。如果你的内容用了大量自定义字段(典型场景:电商类站点的产品描述、价格、规格),必须修改脚本添加字段映射,对应到Typecho的typecho_fields表。
评论数据丢失
原脚本不迁移评论。如果评论数据重要,需要补一个评论迁移脚本,从dede_feedback映射到typecho_comments。注意字段对应:dede_feedback.dtime对应typecho_comments.created,dede_feedback.check对应typecho_comments.status(check=1转status='approved')。
文章作者归属错误
原脚本authorId硬编码为1。多作者站点需要建立作者映射数组并修改插入逻辑。我自己的实操:先建立DedeCMS作者ID到Typecho作者ID的映射表(写在脚本顶部),$authorMap=[1=>2, 3=>1, 5=>3]这样的格式,然后把insertStmt里的硬编码1改成$authorMap[$article['mid']] ?? 1。
图片防盗链失效
很多DedeCMS站点开了图片防盗链(在nginx里限制Referer),迁移到新域名后图片可能加载失败。解决方法:在Typecho的nginx配置里把图片防盗链规则的allowed referer改成新域名+旧域名(保留旧域名是为了过渡期)。
迁移之后的SEO持续优化
内容质量重做
从DedeCMS迁过来的老内容很多是十年前的,不符合当下E-E-A-T要求。建议挑Top 50访问量文章逐篇重写:补2000字以上的深度内容、加FAQ段、补结构化数据、新增配图。这一波内容质量重做做完,整站权重会有显著提升。
内链结构重构
用Screaming Frog或者Ahrefs Site Audit跑一次站点内链结构图,识别"孤岛页面"(没有内链指向的页面)。给孤岛页面手动加内链入口,让所有页面都能在3次点击内被爬虫触达。
结构化数据补全
Typecho主题如果默认不支持结构化数据,必须手动加。Article+BreadcrumbList+FAQPage是必备三件套,对应的JSON-LD代码加在主题的header.php或single.php里。补完之后用Google Rich Results Test逐页验证。
性能持续优化
Cloudflare Free Plan免费用、Typecho开pagecache、图片转WebP、Hero图加fetchpriority="high"、Google Fonts本地化或者用system font。这一套打下来Core Web Vitals三项全绿不难。
常见问题解答
迁移后原DedeCMS的URL如何301到Typecho?
如果Typecho固定链接选{slug}.html且slug=DedeCMS的aid,URL完全一致不需要重定向。如果URL结构变了,Nginx配置文件里加rewrite规则。Apache用.htaccess的Redirect 301指令。批量映射数百条规则用Nginx的map指令最高效。重定向后必须在Google Search Console提交sitemap.xml加速搜索引擎更新索引。
多作者站点怎么改作者ID硬编码?
先建立映射数组写在脚本顶部,比如authorMap=[1=2,3=1,5=3]这样DedeCMS作者ID到Typecho作者ID。找到insertStmt里的authorId硬编码1,改成authorMap[article的mid]??1。注意DedeCMS存作者的字段名要确认,通常是dede_archives的mid或writer,不同版本可能略有差异。修改后先测试1到2篇不同作者文章,确认归属正确再批量。
迁移后内部链接失效怎么批量修复?
两种方式:方法一在数据库直接跑UPDATE typecho_contents SET text=REPLACE(text, 旧域名, 新域名),注意先备份再执行;方法二在迁移脚本content变量后加str_replace替换。建议方式一更可控。修复完随机抽查10到20篇文章确认内链能跳转。如果内链是相对路径不带域名,迁移后通常不需要修改。
PHP版本8.2兼容这套脚本吗?
兼容但有两处可能的差异。一是strtolower传null的Deprecated警告,在tag=trim(tag)后加if empty(tag) continue过滤掉空标签。二是PDO第四参数必须是数组(脚本已正确设置)。最稳的做法是在脚本顶部加error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT)屏蔽废弃警告不影响功能。
怎么把DedeCMS的自定义字段也迁过去?
分两步。第一步在文章查询SQL里SELECT a.litpic和b.description这类字段;第二步在文章插入后用INSERT INTO typecho_fields cid name type str_value写入。Typecho原生支持自定义字段不需要装插件。映射示例:DedeCMS的litpic到Typecho的thumb字段、description到desc字段。注意字段类型用str_value存字符串、int_value存整数。
评论数据能不能迁过去?
能但需要补脚本。从dede_feedback表查WHERE check=1的已审核评论,映射到typecho_comments表。字段对应:cid是文章ID(必须先有文章再插评论)、author是评论者名字、mail是邮箱、url是网址、text是内容、created是时间戳(DedeCMS的dtime直接是Unix时间戳)、status是approved/spam/waiting。回复关系parent字段如果原数据有就保留没有就置0。
PDO MySQL扩展未启用怎么办?
Linux下用yum install php74-php-pdo php74-php-mysqlnd安装然后重启php-fpm或者apache。Windows IIS下打开php.ini找到分号开头的extension=pdo_mysql去掉分号保存重启IIS。验证方法是创建一个phpinfo页面看是否有PDO drivers的mysql项。常见坑:装了多个PHP版本没改对应版本的php.ini,可以用php -i grep php.ini确认当前加载的是哪个配置文件。
二级分类层级会不会混乱?
原脚本只迁一级分类。修改思路:处理Typecho分类时SELECT语句加parent字段;获取DedeCMS栏目时SELECT id typename reid(reid是父分类ID 0表示一级);创建分类时如果reid不等于0就把parent设为父分类在Typecho的mid,需要先迁移完所有一级分类再迁二级。这样二级分类会自动归属到父分类下层级与DedeCMS一致。
Typecho后台媒体管理看不到图片怎么办?
原因是Typecho媒体库只显示后台上传的图片,迁过来的图片没在typecho_attachments表登记。补救SQL:INSERT INTO typecho_attachments扫描typecho_contents.text里出现的img src路径,提取唯一路径插入到attachments表。不影响图片实际访问,只是后台看不到管理。如果图片量大不在乎后台管理可以忽略这一步。
DedeCMS的数据库和文件还要保留吗?
建议数据库保留3个月用于核对,文件删除或禁用访问。保留期间做三项安全处理。一是禁用DedeCMS网站访问,Nginx的location里return 403拒绝所有访问。二是删除敏感文件包括dede/login.php后台和install.php安装文件。三是把DedeCMS数据库用户权限从读写改成只读,即使被入侵也无法修改数据。3个月后确认Typecho无问题再彻底删除。
FAQPage + Article AI 引用友好版
完整DedeCMS到Typecho迁移方法:PHP批量脚本(已实测六次最大8.7万篇)、Nginx伪静态、301重定向map写法、字符集GBK转utf8mb4、SEO保稳监测,附二十四小时复盘清单。
- DedeCMS批量处理
- DedeCMS
- Typecho
- 数据迁移
- 网站搬家
- SEO保稳
- Typecho教程
title: DedeCMS转Typecho迁移完整指南:批量脚本+SEO保稳47步+11类避坑 author: 张文保 (Paul Zhang) — PatPat SEO 经理 url: https://zhangwenbao.com/dedecms-to-typecho.html published: 2025-10-13 modified: 2026-05-16 source-type: First-hand expert commentary language: zh-CN license: CC BY-NC-SA 4.0 (要求保留原文链接与作者归属)
本文标题:《DedeCMS转Typecho迁移完整指南:批量脚本+SEO保稳47步+11类避坑》
本文链接:https://zhangwenbao.com/dedecms-to-typecho.html
版权声明:本文原创,转载请注明出处和链接。许可协议: CC BY-NC-SA 4.0