搜索
系统检测到您的用户名不符合规范:

ThinkPHP3.1在PHP7下页面空白的解决方案

浏览:7565 发布日期:2016年06月28日 分类:技术分享
先把BUG原因扔出来:模板解析出了问题。


之前一直用PHP5.6做开发,听说过PHP出7了,不过一直没尝试。直到前两天,处理(大于2038年 || 小于1900年)时间戳,发现mktime()返回False的问题,才意识到,估计不换是不行了。这明显是超出了取值范围,但2038年的问题按理说只存在于32位系统下,我系统是64位,那就只能是PHP的问题了。果断升级到7,问题解决。

但是,但是,但是!解决问题的同时往往会制造新的麻烦。此乃真理~ 所以,所有使用了模板的页面全都空白了。

初步怀疑是模板解析出了问题,追变量吧。display()、fetch()、tag()、B()这几个函数看下来,还是没能解决问题。因为B()里边是以这种形式进行调用的:$behavior->$method($params); 不太方便追踪,都打印出来又乱(我是个得了懒癌的强迫症),于是换一种简单的思路,读Log。

运行完页面,看Log如下(节选):NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead D:\PHP\WWW\ThinkPHP\Lib\Core\Db.class.php 第 605 行.
NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead D:\PHP\WWW\ThinkPHP\Lib\Template\ThinkTemplate.class.php 第 273 行.
NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead D:\PHP\WWW\ThinkPHP\Lib\Template\ThinkTemplate.class.php 第 168 行.
NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead D:\PHP\WWW\ThinkPHP\Lib\Template\ThinkTemplate.class.php 第 404 行.
NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead D:\PHP\WWW\ThinkPHP\Lib\Template\ThinkTemplate.class.php 第 404 行.
NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead D:\PHP\WWW\ThinkPHP\Lib\Template\ThinkTemplate.class.php 第 404 行.
NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead D:\PHP\WWW\ThinkPHP\Lib\Template\ThinkTemplate.class.php 第 404 行.
NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead D:\PHP\WWW\ThinkPHP\Lib\Template\ThinkTemplate.class.php 第 399 行.
NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead D:\PHP\WWW\ThinkPHP\Lib\Template\ThinkTemplate.class.php 第 404 行.
NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead D:\PHP\WWW\ThinkPHP\Lib\Template\ThinkTemplate.class.php 第 404 行.
NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead D:\PHP\WWW\ThinkPHP\Lib\Template\ThinkTemplate.class.php 第 404 行.
NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead D:\PHP\WWW\ThinkPHP\Lib\Template\ThinkTemplate.class.php 第 404 行.
NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead D:\PHP\WWW\ThinkPHP\Lib\Template\ThinkTemplate.class.php 第 197 行.
NOTIC: [2] preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead D:\PHP\WWW\ThinkPHP\Lib\Template\ThinkTemplate.class.php 第 137 行.
错误基本都在ThinkTemplate.class.php里,看文件名,这个是操作模板的。错误的原因是因为PHP7里删除了preg_replace()的/e参数,其实这个参数在PHP5里就已经废除了,只不过没有删除,所以还能用。官方给出的建议是,用preg_replace_callback()代替preg_replace() /e。

以ThinkTemplate.class.php 第 404 行左右的代码为例,修改如下:if(!$closeTag)
{
/*
$patterns = '/'.$begin.$parseTag.$n1.'\/(\s*?)'.$end.'/eis';
$replacement = "\$this->parseXmlTag('$tagLib', '$tag', '1ドル', '')";
$content = preg_replace($patterns, $replacement, $content);
*/

// By Legolas 2016年06月28日 00:59
$patterns = '/'.$begin.$parseTag.$n1.'\/(\s*?)'.$end.'/is';
$content = preg_replace_callback($patterns, function($match)use($tagLib, $tag){return $this->parseXmlTag($tagLib, $tag, $match[1], '');},$content);
}
else
{
/*
$patterns = '/'.$begin.$parseTag.$n1.$end.'(.*?)'.$begin.'\/'.$parseTag.'(\s*?)'.$end.'/eis';
$replacement = "\$this->parseXmlTag('$tagLib', '$tag', '1ドル', '2ドル')";
for($i=0; $i<$level; $i++)
{
$content = preg_replace($patterns, $replacement, $content);
}
*/
// By Legolas 2016年06月28日 00:52
$patterns = '/'.$begin.$parseTag.$n1.$end.'(.*?)'.$begin.'\/'.$parseTag.'(\s*?)'.$end.'/is';
for($i=0; $i<$level; $i++)
{
$content = preg_replace_callback($patterns, function ($match)use($tagLib, $tag){return $this->parseXmlTag($tagLib, $tag, $match[1], $match[2]);}, $content);
}
}
把Log中报错的位置都改掉,页面就可以正常显示了。

关于正则,再多说两句:
1、正则中,"/1"、"1ドル"表示第一个括号匹配的内容,"/2"、"2ドル"表示第二个括号匹配的内容,依此类推。
2、官方建议,preg_replace_callback()的回调使用匿名函数,参数$match为正则匹配的结果(数组),$match[1]表示第一个括号匹配的内容,依此类推。
3、若匿名函数需要使用外部变量,需要在定义函数时,使用use()传参。


我花了点时间,把代码里全部使用preg_replace() /e的地方,全都替换成了preg_replace_callback(),跟我一样得了懒癌不爱动手的朋友可以直接下载http://code.taobao.org/svn/share2016/trunk/ThinkPHP_Repaire.rar。如果发现BUG,欢迎指正。另外,这个框架因为是日常工作中用的,所以还集成了支付宝网页支付、极光推送、小米推送、PHPMail的第三方类库,都放在Extend\Vendor里,需要的可以直接拿来用~
最佳答案
评论() 相关
后面还有条评论,
评论支持使用[code][/code]标签添加代码
您需要登录后才可以评论 登录 | 立即注册
收藏
13478993703
积分:286 等级:LV1
热点推荐
(追記) (追記ここまで)
最新更新

我们

合作

网站

信息

ThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架 ,创立于2006年初,遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。并且拥有众多的原创功能和特性,在社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进,已经成长为国内最领先和最具影响力的WEB应用开发框架,众多的典型案例确保可以稳定用于商业以及门户级的开发。

AltStyle によって変換されたページ (->オリジナル) /