ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

PHPCMS V9.6.6 修改版实战:SSO 摘除与 PHP7 适配指南

PHPCMS V9.6.6 修改版实战:SSO 摘除与 PHP7 适配指南

简介:PHPCMS V9.6.6 修改版面向仍在使用 PHPCMS 搭建门户、资讯站点的开发者与运维人员,重点解决原版在 PHP8、MySQL8+ 与 HTTPS 环境下兼容性不足、Flash 上传与裁切被淘汰、官方关键词接口失效等痛点。包内为 rar 压缩包,约 20.04MB,文件总数上游未提供,主要涉及 PHP 程序文件、前端 HTML5 与 JS 资源及后台模板,覆盖安装、内容、附件与编辑器等模块。已有 273 人学习下载。改动集中在兼容性与易用性:支持 PHP8、MySQL8+ 与 HTTPS,目录改为 CMS,移除 PHPSSO、视频模块与在线升级;上传与缩略图裁切全面转向 H5,整合 UEditor 并升级至 CK4.16.1,新增水印、附件选择器 UI 与本地图片自动上传;补充讯飞、百度及本地关键词接口,新增站点、栏目、单网页自定义字段与一键导入微信文章、Word 导入字段;同时修复已知 BUG 与安全漏洞,登录密码加密传输,安装时可自定义后台地址并自动清理安装目录与演示数据,另新增大量辅助函数与手机端配置,便于二次开发与长期维护。

1. 拿到一份 PHPCMS V9.6.6 修改版,先搞清楚它到底改了什么

去年帮一个做本地生活资讯的朋友迁站,他丢过来一个压缩包,说“这是 PHPCMS V9.6.6 修改版,PHPSSO 已经去掉了,你直接跑”。我解压一看,目录里确实没有phpsso那一层,api下也少了 SSO 回调文件,但system/config里还留着phpsso相关的配置项,后台登录页的模板也还挂着旧标签。这就是修改版项目的典型状态:核心改动做了,边角料没扫干净。PHPCMS V9.6.6 本身是一套基于 PHP 的内容管理系统,自带模型、栏目、会员、采集、模板引擎,适合做资讯站、门户站、企业站;这个修改版把原版强依赖的 PHPSSO 单点登录模块摘掉了,同时往 PHP7 和 HTML5 前端方向做了适配。适合谁?手里有老 V9 站点要升级、又不想被 SSO 那套跨站登录拖着的开发者,以及想拿一套完整 CMS 源码练手二次开发的人。下面按“能干什么 → 怎么跑 → 怎么改”拆开讲。

2. 目录结构与技术栈:先看清这套 CMS 的骨架

2.1 顶层目录逐个说

解压后第一层目录基本是固定的,我按实际打开的顺序列一下,方便你对照自己的包:

目录/文件作用修改版里的变化
index.php前台入口,加载框架并分发基本不动
admin.php后台入口登录逻辑去掉了 SSO 跳转
api/对外接口目录phpsso.php一类文件被移除
caches/模板编译、配置缓存需要可写
phpcms/框架核心,modules、model、libs都在里面会员模块的 SSO 调用被摘掉
statics/CSS、JS、图片部分模板换成 HTML5 标签
uploadfile/上传文件落盘位置需要可写
install/安装向导装完建议删掉

phpcms/是重点,进去后modules放业务模块(内容、会员、评论、采集等),model放数据模型,libs/functions放全局函数,libs/classes放核心类。修改版对 SSO 的清理主要落在modules/member和api两处,框架层没大动,所以原版的大部分开发习惯还能沿用。

2.2 技术栈与运行环境

这套东西是典型的 LAMP/LNMP 组合:PHP + MySQL + Apache/Nginx,模板引擎是自研的,不是 Smarty 也不是 Twig,语法是{pc:content action="lists" ...}这种标签式调用。修改版往 PHP7 靠,意味着原版里一些mysql_*老写法、each()、ereg之类的东西需要确认是否已经替换。前端侧往 HTML5 走,主要是模板里<!DOCTYPE html>、语义化标签、表单required这类改动,JS 还是 jQuery 那一套,没有上构建工具。

提示:PHP7 下跑 V9 系代码,最先翻车的往往不是业务逻辑,而是老扩展函数和严格模式下的类型告警。先把error_reporting开到E_ALL跑一遍前台,比装完就上线稳。

2.3 请求是怎么走完一圈的

前台一个列表页请求进来,index.php引入phpcms/base.php完成常量定义和自动加载,然后根据 URL 参数解析出模块、控制器、动作,落到modules/content下对应文件,控制器调model取数据,再交给模板引擎编译template/下的模板,编译结果写进caches/caches_template,最后输出。后台请求走admin.php,多一层权限校验。理解这条链路,后面改模板、加接口才知道该动哪一层。

3. 把项目跑起来:环境、安装与首屏验证

3.1 环境准备与建库

我一般用 PHP 7.4 配 MySQL 5.7 先跑通,PHP 8 不是不能试,但 V9 系在 8 上有几处不兼容,新手别一上来就挑战。Nginx 或 Apache 都行,关键是伪静态和目录权限。先建库:

CREATE DATABASE phpcms_demo DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER 'pc_user'@'localhost' IDENTIFIED BY '换成你的密码'; GRANT ALL PRIVILEGES ON phpcms_demo.* TO 'pc_user'@'localhost'; FLUSH PRIVILEGES;

字符集用utf8mb4,别用老教程里的utf8,不然前台发带 emoji 的评论会截断。库建好后,把install/目录留着,浏览器访问站点根路径会进安装向导,按提示填库名、账号、密码,管理员账号自己设一个强口令。

3.2 目录权限与伪静态

安装向导会检查目录可写性,caches/、uploadfile/、html/(如果开了静态生成)这几个必须可写。Linux 下常见做法是给 web 用户组写权限:

chown -R www-data:www-data caches uploadfile chmod -R 755 caches uploadfile

伪静态这块,Nginx 下把官方规则贴进 server 块,核心是把index.php?m=content&c=index&a=lists这类地址重写成路径形式。规则不对的典型表现是首页能开、内页 404,别急着怀疑代码,先看 rewrite 日志。

3.3 装完先做三件事

第一,删install/目录,这是血泪经验,留着等于把重装入口挂在公网。第二,进后台“系统设置”里把phpsso相关开关确认关掉,修改版虽然摘了模块,配置项可能还在,开着会报连接失败。第三,前台随便点一个栏目页、一篇内容页、一次会员登录,确认这三条链路都通。会员登录是重点,因为 SSO 摘除后登录逻辑改成了本地会话,这里最容易出问题。

# 快速探一下关键页面状态码 curl -I http://你的域名/ curl -I http://你的域名/index.php?m=content&c=index&a=lists&catid=1 curl -I http://你的域名/index.php?m=member&c=index&a=login

三个都返回 200 才算首屏验证通过。有一个 500,就去caches/下看错误日志,或者临时把define('DEBUG', true)打开看堆栈。

4. 核心模块拆解:模板标签、会员登录与 SSO 摘除

4.1 模板标签怎么调数据

V9 的模板不是纯 PHP,而是标签语法。一个内容列表的典型写法:

{pc:content action="lists" catid="1" num="10" order="id DESC" page="$page"} {loop $data $r} <li> <a href="{$r[url]}">{$r[title]}</a> <span>{date('Y-m-d', $r[inputtime])}</span> </li> {/loop} {/pc}

action="lists"指定调列表方法,catid是栏目 ID,num是条数,order是排序,page="$page"接分页变量。这段标签最终会被编译成 PHP 去调content模块的lists方法。改模板时记住一点:标签里的参数名对应的是模型方法参数,不是随便起的,写错参数名不会报错,只会静默返回空数据,这是新手最常踩的坑。

4.2 会员登录:SSO 摘掉后改成了什么

原版会员登录会先跳 PHPSSO 做跨站认证,再回跳写本地会话。修改版把这条链路砍了,登录直接走本地。核心逻辑在modules/member/classes下的登录处理里,简化后的流程是这样:

// 简化示意:本地登录校验,不再请求 phpsso public function login() { $username = trim($_POST['username']); $password = $_POST['password']; if (empty($username) || empty($password)) { return ['status' => 0, 'msg' => '账号或密码为空']; } $member = $this->db->get_one( "SELECT userid, username, password, salt FROM v9_member WHERE username = ?", [$username] ); if (!$member) { return ['status' => 0, 'msg' => '账号不存在']; } // V9 的密码是 md5(password + salt) 这类组合,按实际字段核对 if (md5($password . $member['salt']) !== $member['password']) { return ['status' => 0, 'msg' => '密码错误']; } $_SESSION['userid'] = $member['userid']; $_SESSION['username'] = $member['username']; return ['status' => 1, 'msg' => '登录成功']; }

参数说明:username、password来自表单;salt是每个用户独立的盐值,存在会员表里;校验通过后只写本地$_SESSION,不再有 SSO 的 token 交换。改造时要注意两点:一是原版可能有phpsso的 cookie 清理逻辑,摘模块后要一并删掉,否则退出登录会残留;二是如果站点以前和别的系统共用过 SSO 账号,迁移时密码哈希规则可能对不上,需要让用户重置密码,别硬兼容。

4.3 后台入口与权限校验

后台admin.php进来后先查管理员会话,再按角色加载菜单权限。修改版这里没大改,但如果你要加自定义菜单,得同时改phpcms/modules/admin/menu相关配置和角色权限表,只改一边会出现“菜单看得见、点进去没权限”的玄学现象。权限判断最终落在modules/admin/classes的权限类里,调试时直接在那个类里打日志最快。

5. 避坑与排查:PHP7 适配和 SSO 残留的常见问题

5.1 前台白屏但状态码 200

现象:页面打开一片空白,浏览器状态 200,caches/下没有明显报错。原因多半是模板编译失败被静默吞了,或者 PHP7 下某个老函数被禁用。解决:临时在入口打开DEBUG,把display_errors打开,再刷一次,堆栈会直接打出来;同时检查php.ini的disable_functions有没有误禁scandir、file_get_contents这类模板编译要用的函数。

5.2 会员登录一直提示“连接失败”

现象:点登录转圈后报连接失败。原因:SSO 模块虽然删了,但配置里phpsso_server地址还在,登录逻辑某处仍尝试请求。解决:全局搜phpsso关键字,把system/config里的配置项、模板里的隐藏域、JS 里的回调地址一并清掉;再确认api/下没有残留的 SSO 接口文件被其他模块引用。

5.3 上传图片报“目录不可写”

现象:后台上传成功但前台不显示,或直接报错。原因:uploadfile/权限不对,或者 PHP7 下move_uploaded_file的临时目录配置有问题。解决:先确认目录属主是 web 用户,再看php.ini的upload_tmp_dir是否可写;如果用了对象存储插件,检查插件是否兼容当前 PHP 版本。

5.4 伪静态下分页 404

现象:列表第一页正常,点第二页 404。原因:分页链接生成规则和 rewrite 规则不匹配,常见于page="$page"参数没被正确重写。解决:对比浏览器地址栏的实际 URL 和 Nginx 规则,把分页参数补进 rewrite 条件;或者临时关掉伪静态,用动态地址验证是不是规则问题。

5.5 后台登录后马上掉线

现象:登录成功跳转后又被踢回登录页。原因:会话目录不可写,或session配置的save_path指向了不存在的目录。解决:检查php.ini的session.save_path,确保目录存在且可写;如果用了多台机器负载,会话要统一存储,别各存各的。

6. 二次开发怎么下手:从改模板到加模块的稳妥路径

拿到这套修改版,最稳的改造顺序是“先模板、再模型、最后模块”,别一上来就动框架。改模板最安全,template/下按栏目建目录,改完清caches/caches_template就能看到效果,翻车了直接还原文件。加字段走模型层,后台“内容模型”里加字段后,记得同步改对应模板的标签输出,不然数据存了但前台不显示。真要加新模块,照modules/content的结构复制一份,改模块名、控制器名、模型名,再在后台菜单和权限表里注册,这条路径比从零写省事得多。

验证方法我习惯用“三查”:查日志(caches/下的错误日志)、查 SQL(把模型方法里的查询打出来看条件对不对)、查缓存(改完配置先清caches/configs和模板缓存)。二次开发里最容易被忽略的是缓存,V9 的配置和模板都走缓存,改完不生效先怀疑缓存,别怀疑人生。

有个具体技巧值得说:给自定义模块加接口时,别直接改api/下的公共文件,在模块目录里单独建一个api.php,通过模块路由访问,这样升级或替换公共接口时不会互相牵连。我早期图省事往公共api里塞逻辑,后来换版本时被覆盖过一次,从那以后每次加接口都强制走模块内独立文件,再没丢过代码。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进