1. 为什么还有人装 DedeCMS v5.6:需求盘点与判断依据
聊 DedeCMS v5.6 的安装与迁移,先得把一件事说清楚:这不是一个"新项目选型"的话题,而是一个"存量系统维护"的话题。我近几年接手的活儿里,凡是提到这个版本的,几乎都是同一类场景——某个老站点跑在好几年前的服务器上,后台还能进,文章还能发,但服务器要到期了、机房要换、系统要重装,于是整站必须原封不动地搬到新环境里,同时还要顺手把安装流程重新走一遍,确认没有遗漏文件。这类需求的核心不是"我要不要用这个 CMS",而是"我手上这套东西怎么安全地换一个地方继续跑"。
所以这篇文章的定位很明确:给那些手里已经有一套 DedeCMS v5.6 站点、需要重新部署或者整站搬迁的人看。你会遇到的具体问题包括:新服务器上 PHP 版本太高导致白屏、数据库导入后后台登录不上、迁移完成首页能开但内页全是 404、图片路径写死了旧域名导致附件全丢、后台目录暴露被人扫。这些问题我在实际操作里基本都踩过一遍,下面按"判断—准备—安装—迁移—验证—排错—加固"的顺序拆开讲,每一步都给出可直接照抄的命令和配置,也会说明为什么这么做。
需要提前提醒一句:v5.6 属于相当早期的分支,它的代码风格、目录结构和默认配置都停留在那个年代的思路里。这意味着两件事。第一,它对运行环境有比较明确的"舒适区",PHP 5.2 到 5.4 这段是它最适应的区间,贸然上高版本 PHP 会碰到一堆兼容性报错。第二,它的默认安装包里有不少历史遗留问题,比如安装目录没有自动删除、后台路径固定、默认表前缀固定,这些在当年不算大事,放到今天就是明显的风险点。安装和迁移的过程,本质上就是"让它跑起来"加"把该堵的口子堵上"这两件事同时做完。
还有一个现实问题:很多人以为迁移就是"打包文件 + 导出数据库 + 导入",三个动作做完就结束了。实际上真正耗时间的是迁移后的核对环节——栏目页、内容页、搜索结果页、附件下载、后台用户权限,每一样都要单独验证。我见过太多案例,首页打开正常就以为大功告成,结果上线三天才发现所有文章配图全是红叉,因为图片地址里带着旧域名。这些坑在后面会逐个展开。
2. 安装之前先把环境定下来:版本搭配与目录规划
2.1 运行环境的版本搭配,别用"最新"思维
安装 DedeCMS v5.6 最容易翻车的地方就是环境版本。很多人习惯性地把服务器装成最新版,PHP 8 加 MySQL 8,然后上传程序一访问,页面一片空白,连报错都没有。原因不复杂:这套代码里大量使用了早期 PHP 的写法,比如用mysql_*系列函数操作数据库,而这类函数在 PHP 7 之后已经被移除;再比如一些老式的构造函数写法、ereg正则、each()遍历等,在高版本里全部失效。代码不会主动告诉你哪里不兼容,它只是安静地返回空页面。
我的建议是用 PHP 5.6 作为折中方案,MySQL 用 5.6 或 5.7,Web 服务器用 Apache 2.4 或者 Nginx 都可以。PHP 5.6 对这套代码的兼容性最好,同时又比 5.2、5.3 多了不少安全修复。如果服务器上必须跑高版本 PHP,那就得准备一份兼容补丁,把mysql_*换成mysqli_*或者 PDO,工作量不小,而且改完之后要逐页验证,不建议新手尝试。实际选择时可以参考下表:
| 组件 | 推荐版本 | 可接受范围 | 说明 |
|---|---|---|---|
| PHP | 5.6 | 5.2 至 5.6 | 高于 7.0 需改代码,不建议 |
| MySQL | 5.6 / 5.7 | 5.1 以上 | 字符集务必选 utf8 |
| Web 服务器 | Apache 2.4 / Nginx 1.1x | 均可 | Nginx 需自行配置伪静态 |
| 操作系统 | 常见 Linux 发行版 | 不限 | 注意文件属主与权限 |
这里有个细节值得单独说:MySQL 5.7 之后的默认sql_mode变得严格,插入空值或者不规范的日期时可能直接报错。如果你把旧数据库导入到新版 MySQL,遇到"字段不能为空"之类的报错,可以在配置文件里把sql_mode调成宽松模式,或者干脆选 5.6 版本避开这个问题。这类兼容性问题的排查成本很高,因为它们往往在运行几天后才在某个特定操作上暴露出来,所以环境选型阶段多花十分钟确认版本,比后面熬夜debug划算得多。
2.2 目录结构速览与权限划分
上传程序之前,先花点时间认一下这套程序的目录结构,后面迁移和排错全靠它。安装包里大致是这么几块:根目录下是入口文件(index.php、list.php、view.php这类),dede目录是后台管理入口,include放核心类库和公共函数,data放配置、缓存、附件相关的数据,templets是模板目录,uploads是上传的图片和附件,plus放一些独立功能页(搜索、评论、友情链接之类),install是安装向导。
data这个目录要特别留意,它下面通常有common.inc.php(数据库连接配置)、cache(缓存文件)、tplcache(模板编译缓存)、sessions(会话文件)、backupdata(数据库备份)。迁移的时候,common.inc.php必须按新环境改写,缓存类目录必须清空,否则会出现"配置改了但页面还是旧的"这种玄学现象。
权限方面,很多人图省事直接chmod -R 777,这是最省事也最危险的做法——任何被上传的脚本都能被执行和改写。合理的做法是把属主给 Web 运行用户,目录 755、文件 644,只有确实需要写入的几个目录单独放宽:
# 假设 Web 运行用户为 www chown -R www:www /var/www/site find /var/www/site -type d -exec chmod 755 {} \; find /var/www/site -type f -exec chmod 644 {} \; # 仅对需要写入的目录放宽 chmod -R 775 /var/www/site/data chmod -R 775 /var/www/site/uploads chmod 775 /var/www/site/templetstemplets目录在后台编辑模板时需要写入权限,如果你不打算在后台改模板,可以收回写权限,改成只能读。这是个小动作,但能减少一类风险:万一后台账号泄露,攻击者至少没法直接往模板里塞代码。
2.3 安装前就该做的三件安全动作
大部分人习惯"先装好再说安全",但这套程序有几个默认值如果你不在安装前改,装完之后再改会麻烦很多。第一件是表前缀,默认是dede_,几乎所有扫描工具都会去试这个前缀。安装向导里允许你自定义,直接改成xx_这类没有规律的前缀,能挡掉相当一部分自动化试探。第二件是后台目录名,默认叫dede,装完登录进去第一件事就应该把它改掉,改成manage_xxx这种不容易猜的名字,改完记得同步修改data/common.inc.php里对应的路径配置,否则后台登录会跳回老地址。
第三件是安装目录。安装向导跑完之后,install目录不会自动消失,而它里面有个重新安装的入口,如果不删,任何人都能通过访问这个地址把整个站点的数据库清空重装。这不是危言耸听,早期大量站点的数据丢失都是这个原因。所以在开始安装之前,心里就要记着这一步:
# 安装完成后立刻执行 rm -rf /var/www/site/install如果担心以后还要用安装包,可以在本地保留一份压缩包,服务器上一定不要留。这三件事都不是技术难点,纯粹是意识问题,但恰恰是最容易被跳过的。
3. 从零装一遍:安装向导里的每个选项都值得想一下
3.1 上传、解压与访问安装入口
准备阶段做完,正式开装。把安装包上传到站点根目录,解压后确认目录结构完整,然后用浏览器访问http://你的域名/install/index.php。这里有个小提示:如果你是把站点部署在子目录里,访问路径要带上子目录名,后面安装向导里填的"安装目录"也要对上,这个值会写进配置,填错了会导致所有内页链接多一层或者少一层路径。
安装向导第一步是许可协议,第二步是环境检测,这一步会列出目录权限、PHP 版本、扩展支持等检查项。看到有红色的项目不要急着点下一步,逐条确认。常见的红色项有两类:一类是目录不可写,按上一节的权限方案改一下就行;另一类是缺少扩展,比如gd库没装,这会导致验证码图片生成不出来,后台登录时验证码是空白的,看起来像"登录不了",实际是根本没渲染出来。mysqli或者mysql扩展缺失也会在这一步报出来,必须补上。
环境检测通过后进入数据库配置页,需要填四项:数据库地址、数据库名、数据库用户名、数据库密码。数据库地址在本机一般填localhost,如果数据库是单独一台机器,就填对应地址。这里有个经验:数据库名和用户名不要用root,单独建一个只对这个库有权限的账号,万一站点被拿下,至少不会波及整台数据库服务器。字符集一定要选utf8,如果选错成latin1,中文内容会变成一堆问号,而且这种乱码是写入时就错了,后期修复要一条条改表,非常麻烦。
3.2 数据表前缀与管理员账号的设置逻辑
接下来向导会让你设置表前缀和管理员账号。表前缀按前面说的换成不常见的,长度别太短。管理员账号这块,建议用户名不要用admin,密码至少十几位,包含大小写和符号。有人会觉得后台反正有验证码,弱密码没关系,但自动化工具对付早期验证码的手段已经很成熟了,别抱侥幸心理。
安装向导跑完后会提示你管理员账号密码,注意这个提示页面上显示的密码有时和你输入的不完全一致(某些版本会做处理),如果之后登录不上,别急着怀疑环境,先确认是不是这个原因。装完立刻做两件事:删install目录,访问后台登录页确认能进。
3.3 装完后的第一轮自检清单
后台能进不等于装好了。我一般会按下面这个清单过一遍,每一项都对应一个真实的故障场景:
- 首页是否正常显示,有没有出现 PHP 报错或者空白;
- 后台"系统"里的站点设置能不能保存,保存后再刷新是否生效;
- 随便发一篇带图片的文章,确认上传功能正常,图片能在前台显示;
- 生成一次栏目页和内容页的静态 HTML,确认生成目录有写入权限;
- 清一次缓存,确认清完之后前台仍然正常;
- 检查
data/common.inc.php里的数据库配置是否与实际一致。
这个清单看着琐碎,但每一项背后都对应着一个具体权限或者配置项。刚装完就发现问题,排查成本最低;等迁移到新服务器再发现,变量就多了,很难判断是迁移操作的问题还是原本就有的问题。
4. 迁移方案怎么选:三条路线的适用场景
4.1 全量文件加数据库:最笨也最可靠的做法
迁移这套系统,主流有三条路线。第一条是全量文件加数据库的整体搬迁,把整个站点目录打包传过去,数据库导出成 SQL 文件再导入。第二条是先在新环境装一套干净的,再按需导入数据库和模板、附件。第三条是只搬数据库,前台模板和附件用备份恢复。三条路里,第一条最笨重但最不容易出错,因为它不涉及任何"重新安装"带来的配置差异,新环境里的文件和旧环境完全一致,只要配置改对就能跑起来。
我一般首选第一条,尤其是站点里有大量历史文章和附件的情况。具体流程:
# 旧服务器:打包站点文件(排除缓存和临时文件) cd /var/www tar -czf site_backup.tar.gz site \ --exclude='site/data/cache/*' \ --exclude='site/data/tplcache/*' \ --exclude='site/data/sessions/*' # 旧服务器:导出数据库 mysqldump -u dbuser -p --default-character-set=utf8 \ --single-transaction --routines=false \ old_db > /tmp/old_db.sql # 新服务器:恢复文件和数据库 tar -xzf site_backup.tar.gz -C /var/www mysql -u dbuser -p --default-character-set=utf8 new_db < /tmp/old_db.sql导出时加--default-character-set=utf8很关键,不加的话在某些环境下导出的文件编码会变,导入后中文全乱。--single-transaction是为了在不锁表的情况下拿到一致性的快照,站点还在运行时导出也不会出问题。
4.2 配置文件改哪些:逐行对照
文件搬过去、数据库导进去之后,第一件事是改data/common.inc.php。这个文件是整套系统的数据库入口,格式大致如下:
<?php // 数据库配置信息 $cfg_dbhost = 'localhost'; // 数据库主机 $cfg_dbname = 'new_db'; // 数据库名 $cfg_dbuser = 'dbuser'; // 数据库用户名 $cfg_dbpwd = 'your_password'; // 数据库密码 $cfg_dbprefix = 'xx_'; // 表前缀,必须与导入的表一致 $cfg_db_language = 'utf8'; // 字符集 ?>容易出错的是$cfg_dbprefix。如果你在旧站用了自定义前缀,新库导入后表名还是带这个前缀的,配置里必须写一致,写错了的表现是首页能开但所有列表页报数据库错误,因为它在找一张不存在的表。$cfg_db_language也必须和导入数据的字符集对上,写错了中文就是乱码。
第二个要改的地方是后台的站点配置,这些值存在数据库的配置表里,不是文件。登录后台进"系统 - 系统基本参数",重点看三项:站点根网址、网页主页链接、CMS 安装目录。如果迁移前后域名变了,这三项必须改;如果站点从子目录搬到了根目录,安装目录要从/subdir改成空。这三项改错的表现很典型:首页能开,但所有链接都指向旧地址,点哪儿都跳回老域名。
4.3 附件与图片路径:迁移里最容易漏的一环
前面提过,最容易在迁移后出问题的就是附件路径。这套系统的图片和附件地址在数据库里存的是完整路径或者以根路径开头的相对路径。如果是/uploads/allimg/xxx.jpg这种根路径,域名变了也没关系;但如果是http://旧域名/uploads/...这种完整地址,迁移后就全断。
处理办法是先在数据库里查一下有多少条记录带着旧域名:
-- 先查,确认影响范围 SELECT COUNT(*) FROM xx_archives WHERE body LIKE '%旧域名%'; SELECT COUNT(*) FROM xx_arctype WHERE typedir LIKE '%旧路径%';确认之后再做替换,替换前务必先备份整库,这个操作没有撤销键:
UPDATE xx_archives SET body = REPLACE(body, 'http://旧域名', 'http://新域名') WHERE body LIKE '%http://旧域名%'; UPDATE xx_arctype SET typedir = REPLACE(typedir, '/旧子目录', '') WHERE typedir LIKE '/旧子目录%';替换完记得清一次缓存,再重新生成静态页。如果没有重新生成,前台读的还是旧缓存里编译好的 HTML,你会以为替换没生效。另外附件目录本身也要完整搬过去,uploads目录下的文件数量往往很大,传输时用rsync比scp更合适,支持断点续传,中断了不用从头再来:
rsync -avz --progress /var/www/site/uploads/ user@新服务器:/var/www/site/uploads/5. 迁移后的验证:从"能打开"到"能正常运营"
5.1 分层验证法:首页、栏目、内容、功能页
迁移做完,很多人打开首页看到正常就宣布完工。我的习惯是分层验证,一层一层往下走,每层都有对应的故障表现。
第一层是首页。首页能开说明入口文件、数据库连接、模板编译这条链路是通的。第二层是栏目页,随便点几个栏目,看列表能不能正常输出,分页能不能翻。这一层出问题的典型表现是空白页或者数据库报错,原因多半是表前缀、栏目配置、模板路径三者之一对不上。第三层是内容页,重点看正文里的图片能不能加载、附件链接能不能下载。第四层是功能页,搜索页、评论页、友情链接页这些独立入口,它们走的是plus目录下的脚本,权限或者伪静态配置不对就会 404。
这个分层的好处是能快速定位问题范围。首页正常但栏目页报错,问题大概率在数据库配置或栏目数据;栏目正常但内容页图片全断,问题在附件路径;页面都能开但翻页 404,问题在伪静态规则。按层排查比一上来就翻日志效率高得多。
5.2 伪静态规则:换服务器之后必须重配
如果旧站用的是 Apache,换到 Nginx 之后伪静态规则必须重写,因为两者语法不通。这类规则不配的表现是所有内页 404,只有首页能开,看起来像"迁移失败",其实文件和数据都好好的,只是 URL 重写没生效。
Nginx 下常见的规则大致长这样,具体路径按自己的目录调整:
location / { index index.php index.html; if (!-e $request_filename) { rewrite ^/list-([0-9]+)-([0-9]+)\.html$ /plus/list.php?tid=$1&PageNo=$2 last; rewrite ^/list-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /plus/list.php?tid=$1&TotalResult=$2&PageNo=$3 last; rewrite ^/view-([0-9]+)-([0-9]+)\.html$ /plus/view.php?aid=$1&pageno=$2 last; rewrite ^/view-([0-9]+)\.html$ /plus/view.php?aid=$1 last; } }配完规则记得重载配置,然后逐类页面测一遍。这里有个坑要提:前台如果生成了静态 HTML,很多页面其实根本不走伪静态,直接读的是磁盘上的.html文件。这种情况下你改伪静态规则测不出效果,要先把静态页删掉再测,或者直接测那些强制动态的入口。
5.3 后台功能与数据完整性核对
前台看着没问题,后台还得单独过一遍。重点核对三块:用户和权限、栏目结构、文章归属。用户这块看后台管理员列表是否完整、密码能否正常登录;栏目结构看层级是否和迁移前一致,有没有出现父栏目丢失导致的孤立栏目;文章归属看文章是否还挂在原来的栏目下,有没有因为栏目 ID 变化而错位。
数据库层面也可以直接对一下数,比在后台一页页翻快得多:
SELECT COUNT(*) AS 文章数 FROM xx_archives; SELECT COUNT(*) AS 栏目数 FROM xx_arctype; SELECT COUNT(*) AS 用户数 FROM xx_admin;把新旧两边的数字对一遍,差得多就说明导入不完整。另外别忘了检查data/backupdata目录,如果旧站有数据库备份文件,一并搬过去,这是最后的保险。迁移过程中我遇到过数据库导入到一半网络断了,表面看导入成功,实际少了几百条记录,就是靠对数发现的。
6. 常见问题排查速查表:这些坑我基本都踩过
6.1 白屏、乱码、连接失败三类高频故障
迁移和安装过程中出问题,绝大多数能归到三类:白屏、乱码、数据库连接失败。白屏最典型的原因是 PHP 版本不兼容,代码报错但错误显示被关掉了,页面就一片空白。排查办法是临时把错误显示打开,在入口文件顶部加两行:
<?php ini_set('display_errors', 'On'); error_reporting(E_ALL);打开之后通常能看到具体报错,比如"函数未定义"就是版本不兼容,"无法连接数据库"就是配置问题。看完记得改回去,生产环境把错误直接显示给访客是不合适的。
乱码基本都是字符集不一致导致的,三个地方要统一:数据库表的字符集、配置里的$cfg_db_language、以及导入导出时的--default-character-set。三处只要有一处不对,中文就会变成问号或者方块。数据库连接失败则要分两步查,先确认账号密码能不能在命令行登录,再确认配置文件的地址和库名是否正确。命令行能连、程序连不上,多半是配置文件里某个值带了多余空格。
6.2 后台进不去与验证码空白
后台进不去这个现象很常见,但原因分好几种。如果登录页能打开、输入账号密码后跳回登录页,多半是会话目录没有写权限,会话文件写不进去,登录状态就存不住。检查data/sessions目录的权限,必要时清空里面的旧文件。如果登录页打开后验证码位置是空白方块,那是gd扩展没装,装完重启 Web 服务就好。
还有一种情况是后台地址改了但配置没同步,访问新地址会跳转到旧地址然后 404。这种要看data/common.inc.php里有没有相关路径配置,或者后台设置里有没有写死后台目录。改完后台目录名之后,我一般会立刻用无痕窗口测一遍登录,避免浏览器缓存造成误判。
6.3 迁移后的隐性坑:缓存与静态页
有一类问题特别隐蔽:你明明改了配置,前台看起来毫无变化。原因通常是缓存或者已经生成的静态页。这套系统的缓存分好几层,data/cache里存配置缓存,data/tplcache里存模板编译结果,前台还有生成好的 HTML 文件。改完配置的正确顺序是:先清缓存目录,再进后台更新一次系统缓存,最后重新生成静态页。
# 清缓存(保留目录本身) rm -rf /var/www/site/data/cache/* rm -rf /var/www/site/data/tplcache/*如果站点文章量很大,全量重新生成静态页会跑很久,建议先只生成首页和几个重点栏目,确认没问题再全量跑。中途如果超时中断,可能生成一半,这时候前台会出现新旧内容混杂,别慌,重新跑一次全量即可。
| 现象 | 大概率原因 | 排查动作 |
|---|---|---|
| 全站白屏 | PHP 版本不兼容 | 打开错误显示看具体报错 |
| 中文变问号 | 字符集不一致 | 核对库、配置、导入参数三处 |
| 内页全 404 | 伪静态未配置 | 检查重写规则并重载 |
| 图片全部不显示 | 附件路径含旧域名 | 数据库批量替换后重新生成 |
| 登录后跳回登录页 | 会话目录不可写 | 检查并清理 sessions 目录 |
| 配置改了不生效 | 缓存或静态页未清 | 清缓存并重新生成 |
7. 老版本跑起来之后的加固与维护
7.1 必做的几个收紧动作
这套系统装好、迁移完,最后一步是把该收的口子收掉,否则等于把一个老房子的大门敞开。按重要性排序,第一是删除install目录,第二是改掉默认后台路径,第三是换掉默认表前缀(这一步在安装时就该做),第四是关闭前台错误显示,第五是限制后台访问来源。
关闭错误显示有两种做法,改入口文件或者在 Web 服务器层面关掉。Apache 下可以在目录配置里加php_flag display_errors off,Nginx 配合 PHP-FPM 则在php.ini里设置。限制后台访问来源是性价比很高的一招,如果后台只在自己办公网络用,直接在服务器配置里加白名单:
location /manage_xxx/ { allow 192.0.2.0/24; deny all; # 其余 PHP 处理配置 }这个配置的意思是只有指定网段能访问后台,其他来源一律拒绝。代价是你在外面用手机登不上,但对绝大多数站点来说这个取舍是划算的。另外建议把data、include这些目录里的敏感文件做访问限制,比如禁止直接访问.inc.php结尾的文件,这类文件被直接请求时可能泄露配置内容。
7.2 备份策略:迁移之后马上要建立的习惯
迁移这件事本身就是一次提醒:你的站点随时可能需要搬家,而搬家时最怕的就是数据不全。所以迁完之后的第一件事,是把备份机制建起来,别等下次出事再想。我的做法是三层:数据库每天定时导出一次,保留最近七天;站点文件每周全量打包一次,附件目录单独增量同步;每次做任何配置改动之前,手动导出一份数据库存本地。
# 每日数据库备份示例 mysqldump -u dbuser -p --default-character-set=utf8 \ --single-transaction new_db \ | gzip > /backup/db_$(date +%F).sql.gz # 删除 7 天前的备份 find /backup -name 'db_*.sql.gz' -mtime +7 -delete备份文件不要和站点放在同一台机器上,这是常识但总有人忽略。同机器备份在硬盘故障或者误删目录时一起没了,等于没备。备份完还要定期验证能不能恢复,我见过备份脚本跑了半年,某天真要恢复时发现文件全是 0 字节,因为磁盘满了之后脚本静默失败。每个月挑一个备份文件在测试环境恢复一次,这个动作花不了多少时间,但能避免最坏的情况。
关于这套老系统的长期维护,我的实际体会是:它的价值在于存量内容和已经形成的栏目结构,不在于技术本身。所以维护思路应该是"尽量少动、动之前先备份、动完立刻验证",而不是追新求变。能跑、能发文章、能正常访问,对一个存量站点来说就已经达标了。至于要不要升级到更新的分支,那是一个需要评估内容迁移成本、模板改造工作量、插件兼容性的独立决策,不应该和这次安装迁移混在一起做。我在实际操作中的做法是先把迁移这件事彻底做完、跑稳一段时间,再单独评估后续的技术路线,两件事分开推进,出问题时边界清晰,排查起来也轻松很多。