织梦报ereg_replace废弃怎么修?2套方案

把织梦搬到PHP 5.3以上就报ereg_replace deprecated?本文从POSIX函数被废弃的根因讲起,给Linux和Windows两种环境分别给出config.php的精确修复代码、str_replace替代方案、PHP 7升级时的6个隐藏雷、以及临时降级与迁移方案的取舍判断。

张文保 更新 21 分钟阅读 3,163 阅读

2017 年前后国内主机商开始大规模把默认 PHP 版本从 5.2/5.3 升到 5.6 甚至 7.x。很多老织梦站长一觉醒来网站后台直接打不开,浏览器里赫然写着一行:

Deprecated: Function ereg_replace() is deprecated in /home/wwwroot/your-site/dede/config.php on line XX

严重一点的连前台都打不开,整个网站白屏。当时我每周接到的求助里至少有三分之一是因为这个报错。这篇笔记把当时整理给客户的解决方案重新梳理一遍,包含根因、Linux/Windows 两套修复办法、PHP 7 与 PHP 8 升级路径、工程化的长期维护建议、以及若干踩坑后的经验补充。所有代码都在 PHP 5.6 / 7.0 / 7.4 / 8.1 四个环境验证过。

错误的根本原因:PHP 5.3 起废弃了 POSIX 正则函数

要解决问题先得明白它怎么来的。ereg_replace 属于 PHP 早期的 POSIX 风格正则扩展(ext/ereg),从 PHP 5.3.0 开始被官方标记为 Deprecated(已废弃),到 PHP 7.0 直接被移除。被替代的是 PCRE 风格的 preg_replace,速度更快、语法更现代,是目前 PHP 唯一推荐的正则方案。

整个 POSIX 正则函数家族在不同 PHP 版本下的命运:

  • ereg / eregi / ereg_replace / eregi_replace / split / spliti / sql_regcase:PHP 5.3 弃用,PHP 7.0 移除
  • each(不是 POSIX 但同期废弃):PHP 7.2 弃用,PHP 8.0 移除
  • create_function:PHP 7.2 弃用,PHP 8.0 移除
  • 魔术引号 magic_quotes_gpc:PHP 5.3 弃用,PHP 5.4 移除

DedeCMS 由于多年没大版本更新,源码里依旧大量保留 ereg_replacespliteregi 等旧函数。一旦把这套老代码扔到 PHP 5.3 以上的主机环境,PHP 解释器就会持续抛出 Deprecated 警告。如果 php.inidisplay_errors = Onerror_reporting 包含 E_DEPRECATED,这些警告就会直接打印到页面,看起来就像"网站坏了"。

强调一句:这不是织梦源码本身被改坏了,也不是空间商在搞鬼,而是 PHP 语言本身的演进让老代码不兼容

三档严重程度:理解你正在面对的版本

不同 PHP 版本的报错严重度不同,应对策略也不同:

  1. PHP 5.3-5.6ereg_replace 仍可用,但持续抛 Deprecated 警告。功能正常,只是页面顶部冒红字。这是最温和的情况,关掉 E_DEPRECATED 输出就行。
  2. PHP 7.0-7.4ereg_replace 直接抛 Fatal Error 整页崩溃。必须改代码或回退 PHP 版本。
  3. PHP 8.0-8.x:除了 ereg 系列还有更多函数被移除(如 each、create_function),织梦源码里出现的多个隐藏雷会同时炸,工作量翻几倍。强烈建议不要把织梦升 PHP 8。

诊断当前版本:在站点根目录建一个 phpinfo.php(用完立刻删除):

<?php phpinfo(); ?>

访问该文件最上面就能看到 PHP 版本号。或者用 SSH 跑 php -v

Linux 主机的修复方法

绝大多数 DedeCMS 站点跑在 Linux 服务器(CentOS/Ubuntu/Debian + Nginx 或 Apache)。修复步骤:

定位文件

用 SFTP 或 SSH 进入服务器,定位到网站根目录下的 dede/config.php。注意 dede 这个目录名很多老站长出于安全考虑改过——比如改成了 admin8848、wjm888 等,需要按你自己的情况找对路径。

如果不确定后台目录在哪,可以 grep 整个站点:

grep -rln "DEDEADMIN" /home/wwwroot/your-site/ --include="*.php"

核心替换:DEDEADMIN 常量定义

用编辑器打开 config.php,定位到这一行:

define('DEDEADMIN', ereg_replace("[/\\]{1,}", '/', dirname(__FILE__) ) );

替换成 PCRE 写法:

define('DEDEADMIN', preg_replace("/[\/\\\\]{1,}/", '/', dirname(__FILE__) ) );

这里有几个细节必须强调,因为我当年帮人改的时候踩过坑:

  • preg_replace 的正则需要使用定界符(这里用 /),而 ereg_replace 不需要。这是两套正则引擎最明显的语法差异。
  • 反斜杠在 PHP 字符串里要写两层,在正则里再要一层转义,所以最终是四个反斜杠 \\\\,看起来吓人但是必须的。少一个反斜杠正则就匹配不到。
  • 替换后保存,建议直接用 UTF-8 无 BOM 编码,避免中文目录路径出问题。Notepad++ 选"以 UTF-8 无 BOM 格式编码",VSCode 在底部状态栏点 UTF-8 with BOM 切换。

刷新网站 Deprecated 报错应该立刻消失。

更稳妥的替代方案

如果你不想琢磨四个反斜杠的正则,最稳妥的方法其实是用 str_replace

define('DEDEADMIN', str_replace('\\', '/', dirname(__FILE__) ));

这个写法不需要正则引擎,效率更高、可读性更好,也不用担心反斜杠转义陷阱。原本 ereg_replace 的目的就是把路径里所有反斜杠或多斜杠统一成单斜杠,str_replace 完全能做到。我后来给客户的标准方案就是这个,几乎没有出错过。

Windows 主机的修复方法

少数站长用 Windows + IIS 主机,路径分隔符是反斜杠。这种环境下用 preg_replace 处理路径反而绕弯,更简洁的方案是直接用 strtr:

define('DEDEADMIN', strtr(dirname(__FILE__), '\\/', '//'));

strtr 的作用是把第一个参数里出现的反斜杠和正斜杠统一替换成正斜杠,效率比 preg_replace 高(不需要正则引擎),代码也更直观。

Windows 路径处理还有一个被忽视的点——盘符大小写。Windows 文件系统不区分盘符大小写(C:\ 和 c:\ 等价),但 PHP 字符串比较是区分的,会导致某些缓存或路径判断逻辑失效。如果你看到 Windows 织梦站偶发"路径不一致"问题,记得给 dirname 结果调用一次 strtolower。

不止一处:建议全站搜索 ereg_replace

刚才修的只是 config.php 里的一处。DedeCMS 源码里其实还有很多地方在用 ereg_replace、split、eregi 等。只改这一处的话进入"采集"、"附件管理"等模块时还会冒出新的报错。推荐用 grep 全站扫一遍:

# Linux 下递归搜索所有 PHP 文件中的 ereg_replace
grep -rn "ereg_replace" /home/wwwroot/your-site/ --include="*.php"

# 同时搜索其他已废弃函数
grep -rnE "ereg_replace|eregi|eregi_replace|split|sql_regcase|each\(|create_function" /home/wwwroot/your-site/ --include="*.php"

# 输出统计
grep -rEc "ereg_replace|eregi" /home/wwwroot/your-site/ --include="*.php" | grep -v ':0$'

搜出来的每一处都要按上面的思路替换。如果替换量大,建议先在本地用 PhpStorm 这类 IDE 做正则批量替换,再上传覆盖。改完务必通过浏览器访问后台所有常用功能至少一次,确认没有新错误冒出来。

批量替换的 sed 一行命令

对于熟悉 shell 的运维,sed 可以一次性把简单情况搞定(先备份再用):

# 备份
cp -r /home/wwwroot/your-site/ /backup/your-site.bak.20260507/

# 简单替换:把 ereg_replace 中没有特殊字符的部分替换为 preg_replace(仅适用于不含路径分隔符的情况)
find /home/wwwroot/your-site/ -name "*.php" -exec sed -i 's/ereg_replace(\("[^"\\]*"\)/preg_replace(\/\1\//g' {} \;

但是路径处理这种带反斜杠的复杂情况 sed 搞不定,必须人工修。批量改完要彻底过一遍。

常见替换映射表

旧(POSIX)新(PCRE)
ereg($pattern, $str)preg_match("/{$pattern}/", $str)
eregi($pattern, $str)preg_match("/{$pattern}/i", $str)
ereg_replace($pat, $rep, $str)preg_replace("/{$pat}/", $rep, $str)
eregi_replace($pat, $rep, $str)preg_replace("/{$pat}/i", $rep, $str)
split($pat, $str)preg_split("/{$pat}/", $str)
spliti($pat, $str)preg_split("/{$pat}/i", $str)

注意 PCRE 与 POSIX 正则语法的几个差异点:PCRE 用 \d 而 POSIX 用 [:digit:];PCRE 支持非贪婪量词(*?、+?)POSIX 不支持;PCRE 支持反向引用 (\1) 而 POSIX 写法不同。所以批量替换后要测试每条正则的实际匹配结果。

PHP 7 升级:除了 ereg 还有这些雷

如果你被空间商强制升级到 PHP 7+,光修 ereg 系列还不够。织梦在 PHP 7 下还会遇到这些问题:

  1. each() 函数被废弃。织梦的某些迭代代码用了 each,PHP 7.2 弃用、PHP 8.0 移除。替换为 foreach。
  2. 魔术引号 magic_quotes_gpc。PHP 5.4 已移除,但织梦代码里有 get_magic_quotes_gpc() 检查,PHP 8 直接 Fatal。
  3. mysql_* 函数。PHP 5.5 弃用、PHP 7.0 移除。织梦的部分插件还在用,必须换成 mysqli_* 或 PDO。
  4. session_register / session_unregister。PHP 5.4 移除。
  5. 变量赋值方式 list($a, $b) = $array在某些情况下行为变化,特别是字符串拆分。
  6. 整型溢出行为变化。PHP 7 整型超出 PHP_INT_MAX 后变浮点而不是从 -PHP_INT_MAX-1 重新开始。
  7. 错误处理机制变化。PHP 7 把许多原来的 Fatal Error 改成可被 try-catch 捕获的 Throwable,但织梦的错误处理代码没适配。

这些坑相加意味着把织梦升到 PHP 7+ 的工作量大约是 50-200 工时,对老站点来说回报远低于直接迁移到现代 CMS

临时降级:在不改代码情况下"假装"修好

如果你急着应付客户而暂时没空改代码,有两个临时方案:

方案一:关掉 Deprecated 输出

在 php.ini 里设置:

error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE
display_errors = Off
log_errors = On
error_log = /var/log/php_errors.log

这样 Deprecated 警告不再打到页面但日志里仍然记录。注意:这只对 PHP 5.6 及以下版本有效。PHP 7+ 上 ereg_replace 是 Fatal Error,靠改 error_reporting 关不掉。

方案二:宝塔面板降级 PHP 版本

在宝塔面板里给该站单独设置 PHP 版本为 5.6:网站 → 域名 → 设置 → PHP 版本。这是不改代码就能恢复的最快方法,但代价是失去 PHP 5.6 之后的所有性能改进和安全更新。PHP 5.6 官方支持已于 2018 年终止,2026 年再用相当于裸奔。

这两个方案都是临时的,根本解决还是改代码或迁移。

工程化建议:长期维护老织梦站的几条原则

做了这么多年织梦,给手上还在维护老站点的朋友几条经验:

1. PHP 版本不要超过 5.6

织梦官方早已停更,强行升 PHP 7.4 或 8.x 靠手工替换几乎修不完所有兼容问题。如果空间商强制升级,要么换主机要么考虑迁移到 Typecho、WordPress 等还在更新的 CMS。2026 年仍跑 PHP 5.6 的代价是失去近 8 年的性能与安全提升,这个账要算清楚

2. 关闭前台的 Deprecated 输出

即使你修不完所有报错,至少在 php.ini 里设置 error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT,让普通访客看不到这些警告,避免影响 SEO(搜索引擎爬虫看到 Deprecated 字符串可能影响内容评估)。

3. 定期备份

织梦站点的备份要做到"数据库 + 上传目录 + 模板目录"三件套缺一不可。建议用 crontab 每天凌晨打包一次到对象存储:

0 3 * * * /usr/bin/mysqldump -u user -p'pass' dedb > /backup/dedb_$(date +\%Y\%m\%d).sql
0 4 * * * tar -czf /backup/site_$(date +\%Y\%m\%d).tar.gz /home/wwwroot/your-site/uploads/

4. 能静态化就静态化

织梦本身就是为静态生成而设计的,把所有列表页、详情页都生成静态 HTML 可以最大程度规避 PHP 兼容性问题——即使 PHP 报错已经生成的静态页依旧可以访问。这是织梦"老但仍能跑"的核心原因。

5. 加 WAF/CDN 屏蔽后台

织梦的安全漏洞多,建议在 Nginx/WAF 层面把 dede 目录的访问限定到固定 IP(运维办公网)。这样即使代码有漏洞攻击者也进不来:

location ~ ^/dede/ {
    allow 你的办公IP;
    deny all;
}

6. 定期跑漏洞扫描

用 wpscan、nikto 这类开源扫描器对自己站点跑一次,发现明确漏洞立即修补或下架。织梦的高危漏洞(任意文件上传、SQL 注入)每年仍有新增 CVE。

什么时候必须迁移:四个红线

说点逆耳的话。出现以下任一情况建议立即从织梦迁出:

  1. 空间商强制升级到 PHP 8:修复工作量超过迁移工作量
  2. 站点曾被入侵或挂马:织梦的漏洞链太长,修一个洞下次还会被利用
  3. 有金融/医疗/政务类敏感数据:合规要求必须用受支持的软件
  4. 团队内已经没有人懂 PHP 5:维护成本指数增长

迁移的可行路径:

  • 内容站:迁 Typecho(最轻量)或 WordPress(生态最广)
  • 电商类:迁 Shopify 或 WooCommerce
  • 门户类:考虑 headless CMS(Strapi、Directus)+ 静态站点生成器
  • 政府/事业单位站:迁国产开源 CMS(如 PHPCMS V9 的开源分支)

迁移成本一次性高(5-50 万元不等,看站点规模),但长期来看是负债清算,越拖代价越大。

常见问题解答

替换后保存上传,前台仍然报错怎么办?

先确认两件事。第一,你修改的是网站根目录下真正在跑的 config.php,而不是本地下载的副本。SFTP 上传完一定要在服务器端 cat 一下确认改了。第二,你的服务器是否有 OPcache 缓存——如果有,需要重启 PHP-FPM 或者执行 opcache_reset() 让修改生效。宝塔面板可以直接在 PHP 设置里点重启。

能不能直接关掉报错,不修代码?

技术上可以,把 error_reporting 设置成 E_ALL 异或 E_DEPRECATED 就能让 Deprecated 警告不再输出。但不推荐这么做,因为 PHP 7.0 开始这些函数会变成 Fatal Error,到时候连关都关不掉,必须改代码。最好趁早把代码改对,不要把问题往后推。

DedeCMS 还值得继续用吗?

实话说不太建议继续用于新站。它最后一次较大的安全更新是 2014 年了,已知的漏洞在外部扫描器上一抓一大把。老站如果短期没法迁移,可以选择关闭后台公网访问加静态化前台加定期人工巡检的姑息方案。新站请优先考虑 WordPress、Typecho 或其他活跃维护的 CMS。继续在织梦上做新建站的 ROI 已经不存在。

替换 ereg_replace 之后还会遇到 split() 报错吗?

会。split 也是 POSIX 正则系列,PHP 5.3 起被废弃,PHP 7 移除。替换思路一样:把 split($pattern, $string) 改成 preg_split('/'.$pattern.'/', $string),注意补上正则定界符。织梦源码里 split 用得也不少,建议跟 ereg_replace 一起用 grep 一次性扫出来全改。

用 str_replace 代替 preg_replace 行不行?

对于路径分隔符这种简单替换完全可以,性能反而更好。原文里 ereg_replace 的目的就是把多个反斜杠或正斜杠统一成单斜杠,用 str_replace('\\', '/', $path) 也能做到。但如果原代码用了真正的正则模式(带 ., *, [a-z] 等),那就必须用 preg_replace 不能用 str_replace。改之前要看清楚原正则的真实用途。

PhpMyAdmin 也报 ereg_replace 怎么办?

那是你装的 phpMyAdmin 版本太老。phpMyAdmin 4.x 之后已经全部用 PCRE,不会有这个问题。直接到 phpmyadmin.net 下载最新版替换 admin 目录即可。这种情况下不要去改 phpMyAdmin 源码——升级版本是更干净的解决方案。

修复完后台能进了,但生成静态页时报错怎么办?

织梦的"生成"功能调用了多个底层模块(include 目录下),可能那些模块里也有 ereg_replace 没修完。建议跑一遍 grep -rn ereg_replace include/ 把这个目录里的所有出现都改完。include 目录是织梦的核心库,几乎所有功能都依赖它,是 ereg_replace 出现密度最高的位置。

2026 年还有多少站在跑老织梦?

没有官方数据,但从我自己接到的咨询量估算,国内 2026 年仍在生产环境跑 DedeCMS 的站点至少在 5-10 万家级别。多数集中在地方门户、企业站、教育系统、政府单位站。这些站普遍长期没人维护,被攻破后用作矿池或代理跳板的案例每月都有。如果你正好在维护这类站,强烈建议尽快制定迁移计划——继续打补丁的边际成本一年比一年高。

分享到
标签
版权声明

本文标题:《织梦报ereg_replace废弃怎么修?2套方案》

本文链接:https://zhangwenbao.com/dedecms-function-ereg-replace-is-deprecated.html

版权声明:本文原创,转载请注明出处和链接。许可协议: CC BY-NC-SA 4.0

继续阅读
发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交