解决Thinkphp3.1不支持PHP7以上版本的解决办法
服务器重装了系统。PHP版本升级为PHP7,结果发现以前用Thinkphp写的一个项目无法运行了。
thinkphp版本使用3.1版。切换为PHP5.6版本时,可以正常使用。
切换为PHP7时,页面显示空白。
追踪框架核心代码,找到核心的模板文件,最终发现是preg_replace函数错误。
查找原因
先打开错误提示
编辑index.php
ini_set('display_errors', '1'); error_reporting(E_ALL); define('APP_DEBUG', true); //修改 define('APP_ERROR_HANDLE',false); |
多处提示
NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead
|
但这些都不是致命错误。一步一步断点调试,发现最终现象是
页面变空白
查看模板缓存,只显示如下信息
<?php if (!defined('THINK_PATH')) exit();?>
|
判断模板渲染出现异常,找到是模板解析出问题。
最终找到Lib\Template\ThinkTemplate.class.php
中parse()
方法。
错误原因
最终错误原因 PHP7中删除了preg_replace()的/e参数,其实这个参数在PHP5里就已经废除了,只不过没有删除,所以还能用。官方给出的建议是,用preg_replace_callback()代替preg_replace() /e。
当然不能直接删除e
,然后替换成用preg_replace_callback
, 需要修改回调方法
官方PHP文档
preg_replace_callback (PHP 4 >= 4.0.5, PHP 5, PHP 7) preg_replace_callback — 执行一个正则表达式搜索并且使用一个回调进行替换 mixed preg_replace_callback ( mixed $pattern , callable $callback , mixed $subject [, int $limit = -1 [, int &$count ]] ) 这个函数的行为除了 可以指定一个 callback 替代 replacement 进行替换 字符串的计算,其他方面等同于 preg_replace()。 |
替换preg_replace函数
修改示例
原方法
$content = preg_replace('/'.$begin.'literal'.$end.'(.*?)'.$begin.'\/literal'.$end.'/eis', "\$this->parseLiteral('\\1')",$content); |
修改为
$content = preg_replace_callback('/'.$begin.'literal'.$end.'(.*?)'.$begin.'\/literal'.$end.'/is', function ($match){$this->parseLiteral($match[1]);},$content); |
说明
- 正则中,“/1”、“$1”表示第一个括号匹配的内容,“/2”、“$2”表示第二个括号匹配的内容,依此类推。
- 官方建议,preg_replace_callback()的回调使用匿名函数,参数$match为正则匹配的结果(数组),$match[1]表示第一个括号匹配的内容,依此类推。
- 若匿名函数需要使用外部变量,需要在定义函数时,使用use()传参。
全局修改
找到这个问题后,在网上查询到,有人已经解决此问题,将整个Thinphp3.1框架的所有错误都修改。并共享出来。
可以直接下载修复后核心包,替换掉,这样就解决了Thinkphp3.1不支持PHP问题。
参考文章ThinkPHP3.1在PHP7下页面空白的解决方案
这篇文章中也有核心包下载地址http://code.taobao.org/svn/share2016/trunk/ThinkPHP_Repaire.rar
文章来源:http://www.pangxieke.com/php/let-thinkphp3.1-support-php7.html
本文由 我爱PHP169 作者:admin 发表,其版权均为 我爱PHP169 所有,文章内容系作者个人观点,不代表 我爱PHP169 对观点赞同或支持。如需转载,请注明文章来源。