简介这份 PHPCMS V9.6.6 修改版面向仍在使用 PHPCMS 搭建门户、资讯或企业站点的开发者与运维人员重点解决原版在 PHP8、MySQL8 及 HTTPS 环境下的兼容与安全问题。修改版将 PHPCMS 目录更名为 CMS移除 PHPSSO、视频模块与在线升级等冗余组件并整合 CK4.16.1 编辑器与 UEditor支持 H5 上传、H5 缩略图裁切及手机电脑同时生成静态页。资源包为 rar 压缩格式大小约 20.04MB内含安装程序、后台与前台模板、上传及图片处理类文件、二维码与 Input 等新增类库以及大量辅助函数与字段扩展文件目录结构经过清理与重组。目前已有 273 人学习下载。读者可据此获得一套可直接部署的兼容性改造方案涵盖后台登录加密、附件分站、自定义字段、关键词 API 与微信文章导入等实用功能并附带已知 BUG 与安全漏洞的修复思路适合需要二次开发或迁移旧站的进阶用户参考。1. 接手一套 PHPCMS V9.6.6 修改版先搞清楚它到底改了什么拿到一套 PHPCMS V9.6.6 修改版第一件事不是急着部署而是搞清楚它和官方原版差在哪。PHPCMS V9.6.6 本身是十几年前的老架构PHP 5.x 时代的产物放到今天的 PHP 7.4 或 8.x 环境里一堆函数废弃、模板标签不兼容、数据库驱动报错。所谓「修改版」通常是前人为了让它跑在新环境上或者为了适配某个具体业务场景动过核心文件、改过模板引擎、打过安全补丁的版本。它解决的核心问题是让你不用从零去啃一个已经停止维护的 CMS直接站在别人踩过的坑上继续走。适合谁适合手里有老站要维护、有二次开发需求、或者需要快速搭一个内容管理后台的开发者。但前提是你得先摸清这套修改版的底细否则后面每一步都是玄学。2. 环境搭建与核心文件改动排查让修改版先跑起来2.1 PHP 版本选择与扩展依赖确认PHPCMS V9.6.6 修改版最常见的翻车点就是 PHP 版本。官方原版设计在 PHP 5.2~5.4 区间修改版如果没做彻底兼容直接上 PHP 8 会大面积报错。我一般先用 PHP 7.4 试水这个版本对老代码相对宽容mysql_*系列函数虽然移除但mysqli和PDO还能兜底。先确认扩展php -m | grep -E mysqli|pdo_mysql|gd|curl|mbstring|json|xml这几个是 PHPCMS 的硬依赖。gd用于缩略图生成mbstring处理中文截取curl负责远程请求比如采集模块json和xml在接口和缓存里用到。缺哪个补哪个别等到安装界面白屏才回头查。如果修改版里还有mysql_connect这类函数残留PHP 7 以上会直接 fatal error。用 grep 扫一遍grep -rn mysql_connect\|mysql_query\|mysql_fetch ./phpcms/ --include*.php | head -30有输出就说明修改版没改干净需要手动替换成mysqli或PDO写法。这一步没有捷径只能逐个文件改。2.2 目录权限与安装入口的隐藏处理PHPCMS 安装时需要写configs/、caches/、uploadfile/这几个目录。权限给不对安装程序会卡在第三步不动页面也不报错就是黑匣子。chown -R www:www ./configs ./caches ./uploadfile ./html chmod -R 755 ./configs ./caches ./uploadfile注意html目录是生成静态页的落点如果修改版启用了静态化这个目录必须可写。另外安装完成后第一件事是删掉install/目录或者至少重命名。修改版有时候会保留安装入口这就是个后悔药都来不及吃的口子。mv ./install ./install_bak_$(date %s)2.3 修改版核心改动的定位方法怎么知道修改版改了哪些核心文件最可靠的办法是拿一份官方原版做 diff。没有原版怎么办看文件修改时间。find ./phpcms -name *.php -newer ./phpcms/base.php -mtime -365 | xargs ls -lt | head -40base.php是框架入口比它新的文件大概率被动过。重点看phpcms/modules/下的控制器和phpcms/libs/classes/下的核心类。常见改动集中在文件路径常见改动目的phpcms/libs/classes/db_mysqli.class.php数据库驱动兼容phpcms/libs/functions/global.func.php全局函数补丁phpcms/modules/admin/后台功能定制phpcms/templates/default/模板标签调整把这些文件单独备份一份后面出问题好回滚。3. 数据库连接与模板引擎适配修改版最容易翻车的两个点3.1 数据库配置文件的参数含义与调试PHPCMS 的数据库配置在configs/database.php修改版可能把它挪到了别处或者加了多数据库支持。先找find ./configs -name *.php | xargs grep -l dbhost\|dbname 2/dev/null找到后看这几个参数?php return array( default array( hostname 127.0.0.1, // 数据库主机别用 localhost 避免 socket 问题 port 3306, // 端口修改版可能改成自定义端口 username phpcms_user, // 数据库用户 password your_password,// 密码 database phpcms_db, // 库名 charset utf8mb4, // 字符集修改版可能还是 utf8 tablepre v9_, // 表前缀安装时设定 ), );charset这里要注意如果修改版没升级到utf8mb4存 emoji 会直接截断。改成utf8mb4后数据库和表也要同步改ALTER DATABASE phpcms_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ALTER TABLE v9_content CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;tablepre别乱改改了要同步改所有 SQL 查询里的前缀修改版如果做过表前缀自定义配置文件里会有说明。3.2 模板标签不兼容的排查与替换PHPCMS 的模板引擎用{tag}和{php}混写PHP 7.4 之后{php}里的某些写法会报错。典型的是each()函数PHP 8 已移除PHP 7.4 废弃。grep -rn each( ./phpcms/templates/ --include*.html | head -20有输出就替换成foreach。模板里常见写法{php $arr explode(,, $keywords)} {loop $arr $k $v} a href{$v}{$v}/a {/loop}{loop}是 PHPCMS 自己的标签底层还是foreach一般没问题。但{php}里如果直接调用了废弃函数就会白屏。排查方法打开configs/config.php里的debug模式把错误显示打开。// configs/config.php define(DEBUG, true);然后刷新页面看报错行号逐个改。3.3 缓存目录的清理与重建修改版跑起来后如果页面显示的还是旧内容或者后台改了东西前台不动九成是缓存问题。PHPCMS 的缓存分两种文件缓存和内存缓存如果修改版集成了 Redis/Memcache。文件缓存在caches/目录下直接清rm -rf ./caches/caches_* ./caches/configs/*注意别把caches/configs/下的系统配置文件删了有些修改版把站点配置放这里。稳妥做法是先备份再清。内存缓存看configs/cache.php?php return array( file array(type file, debug false), // redis array(type redis, host 127.0.0.1, port 6379), );如果启用了 Redis清缓存用redis-cli -h 127.0.0.1 -p 6379 FLUSHDB别用FLUSHALL除非你确认这台 Redis 没有别的业务。4. 避坑与常见问题排查修改版特有的五个血泪教训4.1 后台登录白屏或无限跳转现象输入账号密码后页面空白或者一直跳回登录页。原因修改版可能改了 session 存储方式或者configs/config.php里的auth_key和数据库里的不一致。还有一种情况是 PHP 的session.save_path不可写。解决先看 PHP 错误日志确认是不是 session 问题。然后检查configs/config.phpdefine(AUTH_KEY, xxxxx); // 这个值要和数据库 v9_admin 表里的对得上对不上就手动改数据库里的encrypt字段或者清空v9_admin表的lastloginip和lastlogintime再试。4.2 静态页生成失败但无报错现象后台点「生成静态页」转圈半天最后提示成功但html/目录下没文件。原因修改版可能改了静态化规则或者html/目录权限不对。还有一种隐蔽情况PHP 的open_basedir限制导致无法写入目标目录。解决先确认权限再查php.ini里的open_basedirphp -i | grep open_basedir如果有路径限制把html/目录加进去。然后看phpcms/modules/content/classes/html.class.php里的生成逻辑修改版可能在这里加了钩子。4.3 采集模块乱码或采集不到内容现象采集规则测试通过但实际采集回来的是乱码或者内容为空。原因目标站编码和 PHPCMS 的charset不一致修改版可能没做自动转码。另外curl的User-Agent被目标站拦截。解决在采集规则里强制指定编码// 采集配置里加 charset gbk, // 根据目标站调整如果是User-Agent问题在phpcms/libs/classes/http.class.php里改$user_agent Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36;4.4 上传图片提示「文件类型不允许」现象后台传图明明选的是 jpg却提示类型不允许。原因修改版可能改了configs/upload.php里的允许类型或者 PHP 的fileinfo扩展没开导致 MIME 检测失败。解决先确认fileinfo扩展php -m | grep fileinfo没开就装。然后看configs/upload.phpallowext jpg|jpeg|png|gif|bmp|webp,修改版可能把webp去掉了或者加了奇怪的限制。4.5 修改版升级后原功能失效现象把修改版从 PHP 5.6 迁到 PHP 7.4 后某些自定义功能不工作了。原因修改版里的自定义代码用了 PHP 5 的特性比如ereg、split、mysql_*。解决全局搜索废弃函数grep -rn ereg\|split(\|mysql_\|each( ./phpcms/ --include*.php | grep -v preg_split\|explode逐个替换。ereg换preg_matchsplit换explode或preg_splitmysql_*换mysqli_*。5. 二次开发与安全加固让修改版真正为你所用5.1 自定义模块的创建与钩子注入PHPCMS 的模块机制是它的核心扩展点。修改版如果没动phpcms/modules/的结构你可以按标准流程建模块。先建目录mkdir -p ./phpcms/modules/mymodule/然后建三个核心文件?php // ./phpcms/modules/mymodule/index.php defined(IN_PHPCMS) or exit(No permission resources.); class index { private $db; public function __construct() { $this-db pc_base::load_model(mymodule_model); } public function init() { $data $this-db-select(); include $this-admin_tpl(index); } }?php // ./phpcms/modules/mymodule/mymodule_model.class.php defined(IN_PHPCMS) or exit(No permission resources.); class mymodule_model extends model { public function __construct() { $this-db_config pc_base::load_config(database); $this-db_setting default; $this-table_name mymodule; parent::__construct(); } }?php // ./phpcms/modules/mymodule/install/config.inc.php defined(IN_PHPCMS) or exit(No permission resources.); $module mymodule; $modulename 我的模块; $introduce 自定义模块; $author developer; $version 1.0;建完在后台「模块管理」里安装。钩子注入看phpcms/libs/classes/hook.class.php修改版如果没改这个文件可以用pc_base::load_app_class(hook, mymodule)的方式挂载。5.2 后台入口的二次保护PHPCMS 后台默认路径是/admin.php修改版可能改成了别的。不管改没改都建议加一层保护。最简单的是 IP 白名单在admin.php开头加?php // admin.php $allow_ips array(192.168.1.100, 10.0.0.5); if (!in_array($_SERVER[REMOTE_ADDR], $allow_ips)) { header(HTTP/1.1 403 Forbidden); exit(Access denied); } define(IN_PHPCMS, true); // ... 原有代码如果 IP 不固定用 HTTP Basic Auth?php // admin.php if (!isset($_SERVER[PHP_AUTH_USER])) { header(WWW-Authenticate: Basic realmAdmin Area); header(HTTP/1.0 401 Unauthorized); exit(Authentication required); } if ($_SERVER[PHP_AUTH_USER] ! admin || $_SERVER[PHP_AUTH_PW] ! strong_password_here) { header(HTTP/1.0 401 Unauthorized); exit(Invalid credentials); } define(IN_PHPCMS, true);注意strong_password_here别用弱密码也别和 PHPCMS 后台密码一样。5.3 SQL 注入与 XSS 的针对性修补PHPCMS 原版有一些已知的注入点修改版如果没打补丁需要手动补。重点看phpcms/libs/classes/model.class.php里的select和query方法。如果直接拼接$_GET或$_POST参数就有风险。// 不安全的写法 $sql SELECT * FROM v9_content WHERE id . $_GET[id]; // 安全写法 $id intval($_GET[id]); $sql SELECT * FROM v9_content WHERE id . $id;字符串参数用mysqli_real_escape_string或 PHPCMS 自带的safe_replace$keyword safe_replace($_GET[keyword]);XSS 修补主要在输出环节模板里用htmlspecialchars{$title|htmlspecialchars}PHPCMS 模板支持管道函数这样写就行。5.4 日志监控与异常行为发现修改版跑起来后建议开一个简单的访问日志监控。在phpcms/base.php开头加?php // base.php 顶部 $log date(Y-m-d H:i:s) . . $_SERVER[REMOTE_ADDR] . . $_SERVER[REQUEST_URI] . PHP_EOL; file_put_contents(PHPCMS_PATH . caches/admin_access.log, $log, FILE_APPEND);然后定期看这个日志重点找grep -E union|select|concat|script|eval ./caches/admin_access.log有可疑请求就封 IP。这个办法土但管用。5.5 版本回滚与增量备份策略修改版最怕改崩了回不去。我一般用 git 做版本管理哪怕只有本地仓库cd /path/to/phpcms git init git add . git commit -m init phpcms v9.6.6 modified每次改核心文件前先提交一次。数据库备份用mysqldumpmysqldump -u phpcms_user -p phpcms_db backup_$(date %Y%m%d_%H%M%S).sql增量备份可以用rsyncrsync -avz --delete ./phpcms/ /backup/phpcms_$(date %Y%m%d)/注意--delete会删掉目标目录里多余的文件第一次用先加--dry-run看效果。5.6 一个具体技巧用 Composer 管理第三方依赖PHPCMS 原版没有 Composer 支持但修改版如果引入了第三方库手动管理很痛苦。可以在根目录建composer.json{ require: { php: 7.4, monolog/monolog: ^2.0 }, autoload: { psr-4: { App\\: app/ } } }然后composer install在base.php里引入 autoloadrequire_once PHPCMS_PATH . vendor/autoload.php;这样日志、HTTP 客户端这些轮子直接用现成的不用自己造。但注意别和 PHPCMS 原有的类名冲突命名空间加前缀。我自己的习惯是每次接手一套修改版先花半天时间做 diff 和备份再花半天搭环境跑通最后才动代码。急着改的人最后都在修环境。希望帮到你。本文还有配套的精品资源点击获取