ThinkPHP 3.1.3 Full完整版部署与兼容指南

ThinkPHP 3.1.3 Full完整版部署与兼容指南 简介这份压缩包是ThinkPHP 3.1.3完整版框架面向使用或学习经典PHP框架的开发者、学生及中小型项目团队。ThinkPHP 3.1.3遵循MVC设计模式内置模板引擎支持继承与布局、动态路由、ActiveRecord模型、ORM数据库操作、缓存管理及错误日志等能力兼顾了快速开发与安全防护既适合作传统Web项目的基础框架也适合作为源码分析的教学对象。压缩包大小约1.37MB以PHP源码和默认配置为主解压后即可在支持PHP的环境中运行调试。已有280人学习说明该老版本在入门教学、课程设计和旧项目维护方面仍有较强的参考性。借助这份代码读者能直接搭建ThinkPHP 3.1.3环境对照真实框架代码理解路由分发、模型关联、模板渲染等底层逻辑也能快速复用其内置组件完成业务开发相比从零构建能减少依赖缺失与兼容性排查成本为后续阅读或升级新版框架打下基础。1. 为什么一个十年前的框架版本还有人翻出来用先说实话我第一次看到“ThinkPHP3.1.3_Full完整版”这个标题的时候第一反应是这东西居然还在被下载。ThinkPHP 3.1.3是2013年左右的版本放到今天已经是妥妥的“古物”但实话说这批老版本项目至今还在大量生产环境里跑着国内不少企业的OA、CRM、后台管理系统代码就是从那个时期一路改过来的一代代程序员在上面修修补补框架本身一直没换过。除了遗留项目维护还有两类人也需要这个版本一类是刚入行的新手想搭建一个老环境看看早期的PHP框架长什么样理解MVC、路由、ORM这些概念是怎么一步步演变的另一类是做代码审计、安全评估的技术人员老版本框架的历史漏洞、写法习惯、配置文件结构都是必须吃透的东西。所以“Full完整版”这个词很关键——它不是那个精简的入门包而是把核心库、模式目录、语言包、行为扩展、第三方类库全部打包的版本拿来直接就能部署。这篇就围绕这个老版本讲讲我实际部署和使用3.1.3 Full版折腾出来的经验目录结构怎么拆、新版PHP环境怎么让它跑起来、几个高频操作的正确姿势以及维护这类老项目最值得注意哪些问题。2. 完整版目录逐个拆Common、Conf、Library、Mode、Tpl 各自管什么拿到“ThinkPHP3.1.3_Full完整版”压缩包解压后你会看到最外层有一个ThinkPHP目录下面平铺着一批核心文件和文件夹。很多人第一次打开直接蒙了不知道哪个是核心、哪个能删、哪个千万别动。我按实际用途拆一遍。2.1 核心入口与公共目录ThinkPHP.php是整个框架的唯一入口所有请求最终都会经过这个文件。它负责定义路径常量、加载核心类库、启动框架。Common目录存放公共函数文件其中functions.php是全局函数库像I()、D()、M()这些你天天用的助手函数全在这里定义。这两个位置属于“绝对不能动”的部分。Conf目录存放框架的核心配置文件最常改的是convention.php相当于框架的默认配置公约。例如默认的URL_MODEL就在这里定义如果你要改伪静态规则、调整默认模块、设置默认时区底层默认值都在这一层。注意项目自己的配置写在应用目录的Conf/config.php两者是合并关系不要直接改核心的convention.php。2.2 Library 核心类库与扩展Library是整个框架类库的大本营下面分几个子目录Think目录框架最核心的类比如Think\App、Think\Db、Think\Model、Think\Controller整个生命周期就是靠这些类协作完成的。写M(user)方法能返回模型实例靠的就是Think\Model的工厂逻辑。Behavior目录行为扩展框架内置的ReadHtmlCacheBehavior、WriteHtmlCacheBehavior、TokenBuildBehavior等都在这里。行为机制是ThinkPHP 3.x一个很有意思的设计它允许你在应用执行的不同阶段挂载额外操作。Org目录一些额外的PHP类库例如Org\Net\UploadFile文件上传类、Org\Util\Date日期处理类、Org\Util\String字符串处理类。我印象很深的是很多老代码直接使用Org\Util\String::randString()生成随机字符串。Vendor目录用于放置第三方类库比如老项目里经常把Smarty、PHPExcel、RSA加密库丢在这里通过Vendor(类名)导入。2.3 Mode 模式目录与 Tpl 模板目录Mode目录放的是框架的多种运行模式配置比如普通模式、兼容模式、Cli模式、REST模式。3.1.3支持MODE_NAME配置来切换运行模式REST模式就是在这个版本里进一步完善起来的。绝大多数项目用的是默认普通模式但如果你在维护一个对外提供API的老系统去看Mode/rest.php配置会很有收获。Tpl目录是框架内置的模板引擎目录包含默认模板主题和模板编译相关文件。ThinkPHP 3.1.3自带一套基于PHP的模板引擎支持volist、if这类标签也支持在模板里直接写原生PHP代码。Tpl/default下面可以看到默认模板页面方便快速调试。完整版和基础版最大的区别就在这些外围目录基础版为了精简体积把Lang语言包、Mode模式目录、Tpl模板目录、部分Behavior行为全部瘦身了而Full版全部保留对学习和排查老系统来说是必要资产。3. 新版PHP环境跑旧框架的三个兼容层json扩展、mysql驱动、PHP7语法冲突这部分是整个部署实战里最容易翻车的地方。热搜词里挂着的“thinkphp安装ext-json”说明很多人卡在了扩展上。实际上在较新系统上跑ThinkPHP 3.1.3需要同时面对三层兼容问题。3.1 三层兼容问题的排查链路我上个月帮朋友把一个托管在旧服务器上的3.1.3项目迁移到新机器按顺序排查了这三层每一步都有典型报错记录一下完整链路。第一步PHP版本问题。框架在PHP 5.3时代开发PHP 5.6是它运行最舒服的版本。如果直接丢到PHP 7.4或PHP 8.0下最先出现的是大量Deprecated警告比如花括号偏移访问$str{0}这种写法在PHP 8下直接报错。更麻烦的是each()函数在PHP 8.0被移除、create_function()在PHP 7.2被移除如果老代码用到这些页面直接白屏。我的建议如果只是临时维护首选PHP 5.6.40这是5.x系列最后一个版本兼容性好安全补丁也基本到位。如果是长期维护再考虑PHP 7.4加补丁兼容网上有不少3.1.3兼容PHP 7的补丁主要是把mysql换成mysqli、替换弃用函数。第二步PHP扩展问题。热搜词里的“ext-json”就出现在这一步。PHP 5.6默认没有安装json扩展时ThinkPHP的json_encode、json_decode会直接报“Call to undefined function”常见的报错是Fatal error: Call to undefined function json_encode()。排查方法是在命令行下执行php -m | grep json如果没有输出说明json扩展未安装。PHP 8.0之后json已经成为内置扩展无法移除所以如果是PHP 8环境这一步基本不会遇到。在PHP 5.6下则需要用包管理器安装# Debian/Ubuntu sudo apt-get install php5-json # CentOS/RHEL 6 yum install php-json第三步数据库驱动问题。这是老框架上最普遍的坑。ThinkPHP 3.1.3的数据库驱动默认调用mysql_connect系列函数但PHP 7.0已经把这些函数全部删除。所以如果你在PHP 7以上跑3.1.3必须在config.php里把DB_TYPE配置改为mysqliDB_TYPE mysqli, DB_HOST localhost, DB_NAME your_db, DB_USER your_user, DB_PWD your_password, DB_PORT 3306,注意mysqli驱动在3.1.3里是自带的但它在连接数据库之前会执行一些初始化逻辑个别老版本驱动代码在PHP 7.4下还要小改。遇到Call to undefined function mysql_connect()的报错就那么来先确认DB_TYPE是不是mysqli。3.2 PHP 7.4下跑通3.1.3的最小改动示例如果环境已经锁定PHP 7.4可以参考我实际操作的改动量。先说结论不是不能跑但必须逐个修复“已移除函数”和“变更语法”。以最常见的分页功能为例老代码里可能用了each()while (list($key, $value) each($array)) { // ... }PHP 8.0直接移除each()PHP 7.4虽然还有但已废弃。兼容写法foreach ($array as $key $value) { // ... }再有就是mysql转mysqli后ThinkPHP 3.1.3的驱动文件Lib/Driver/DbMysqli.class.php在某些场景下还会调用mysql_get_server_info之类的函数需要改成mysqli_get_server_info。这种改动不大但必须逐行排查。另一个隐藏问题PHP 7.2之后create_function()被删除如果老项目里用了array_map(create_function(...))这类写法要么改用匿名函数要么加一个兼容函数定义在公共文件里。我的建议是除非你对这套老代码非常熟悉否则不要把生产环境直接升到PHP 7.4。最稳妥的组合是PHP 5.6或PHP 7.0 Apache/Nginx MySQL 5.6/5.7。MySQL 8.0虽然也能配但老版本PDO/mysqli驱动和MySQL 8.0的默认认证插件caching_sha2_password不兼容容易连不上需要建用户时指定mysql_native_password。4. I函数、ORM、模板引擎3.1.3三个日常操作的实测记录理解完整版的目录结构和兼容方案后再看实际开发中每天都要用的三个功能。这里结合热搜词“thinkphp input /d”着重讲I()函数的过滤规则这是3.1.3里最实用也最容易被忽略的能力。4.1 I函数与/d整形过滤ThinkPHP 3.1.3的I()函数接收三个参数变量名、默认值、过滤方法。过滤方法的写法可以是一个PHP函数名也可以是一个正则表达式。热搜词中的“input /d”指的就是I(param, 0, /^\\d$/)这种写法表示只允许数字。实际中我是这么用的$id I(get.id, 0, /^\d$/); if ($id 0) { $this-error(参数错误); }这段代码的作用是从$_GET[id]取值如果不存在或不符合纯数字规则则返回默认值0再做一次业务校验。相比直接写$_GET[id]至少能挡住大部分注入和类型错误。另一个常用过滤是intval和strip_tags。比如接收用户提交的标题$title I(post.title, , strip_tags);如果希望保留基本安全过滤但允许部分标签可以自定义过滤函数。把过滤逻辑写在应用公共文件Common/common.php里全项目都可以调用function safe_html($str) { return htmlspecialchars($str, ENT_QUOTES, UTF-8); }然后在I()里传函数名即可I(post.content, , safe_html)。4.2 ORM链式操作与数据库配置ThinkPHP 3.1.3的数据库操作基于PDO思路但封装有自己的风格最常用的是M()和D()。区别在于M(user)返回一个轻量模型不包含业务逻辑适合快速增删改查D(User)会加载对应的UserModel.class.php可以调用自定义方法。链式操作的风格长这样$user M(user); $list $user-where(status1)-order(id desc)-limit(10)-select();这是3.x最典型的用法。需要注意3.1.3的where字符串条件是直接拼接进SQL的所以开发者必须自己负责条件的安全性。推荐使用数组条件$map[status] 1; $map[username] array(like, %think%); $list $user-where($map)-select();数组条件走的是参数绑定比字符串拼接更安全。这一点在维护老项目时尤其重要因为很多老代码写的是$_GET值直接拼进where审计时要重点排查。4.3 模板引擎的常用标签写法模板目录下Tpl/default是默认主题3.1.3模板语言的核心是volist、if、foreach几个标签。我贴一个最常见的列表写法volist namelist idvo tr td{$vo.id}/td td{$vo.username}/td tda href{:U(User/edit, array(id$vo[id]))}编辑/a/td /tr /volist注意U()函数生成URL地址时3.1.3支持数组参数但如果你在循环里写$vo[id]模板引擎解析时花括号里必须用$vo[id]而不是$vo.id。这两种写法在模板里都能用但混用容易出问题建议统一。另外3.1.3支持在模板中直接使用PHP代码这个特性是一把双刃剑。快速调试时很方便但生产代码里尽量少用因为浏览器报错直接暴露变量名和逻辑维护性差。5. 维护老项目的三件套锁环境、做备份、留文档部署跑通、功能看完最后一个环节是“怎么让老项目安安稳稳地继续活着”。我在一个差不多十年前的项目上断断续续修过几年bug总结下来有三件事最值得做。5.1 锁定运行环境别追新老框架最怕的其实就是“顺手升级”。一次操作系统升级、一次PHP小版本更新都可能让一个稳定的老系统突然白屏。务实的做法是把这套项目所依赖的PHP版本、MySQL版本、Apache/Nginx版本、PHP扩展列表全部写进部署文档并在服务器上锁住版本。如果必须迁移先拿完整版源码在测试环境完整复现一遍把所有页面和接口过一遍再动线上。5.2 目录备份要带版本号ThinkPHP 3.1.3项目里经常改的是应用目录下的Conf、Common、Lib、Tpl四个目录核心框架目录基本不动。我建议备份时至少保留两份一份是完整源码压缩包一份是应用目录差异包。压缩包用于整机恢复差异包用于快速定位生产环境和开发环境的不同这个对不同开发者的本地配置差异排查特别有用。5.3 文档补齐比改代码更重要接手老项目时第一件事不是改功能而是把入口文件、数据库配置、伪静态规则、定时任务、队列脚本、后台地址全部摸清楚整理成一份“项目启动手册”。我见过太多项目倒在“只有作者知道怎么跑起来”这个状态里换个人接手就抓瞎。这份手册可以简单到只有两三页但必须包含数据库账号密码、本地域名配置、PHP版本要求、常用目录说明、发版流程。最后分享一个小经验配置信息里如果有数据库密码或密钥不要把明文提交进代码仓库。老项目往往没有完善的密钥管理系统但至少可以在config.php里用getenv()读取环境变量这样即便源码泄露也不会直接暴露数据库密码。这件事花不了半小时收益却很大。本文还有配套的精品资源点击获取