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

news/2024/8/26 16:58:42
ThinkPHP3.1在PHP7下页面空白的解决方案  
浏览:2057 发布日期: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里,需要的可以直接拿来用~



----------------------------------


thinkphp在php7环境下提示Cannot use ‘String’ as class name as it is reserved的解决方法

作者:小松博客 字体:[增加 减小] 类型:转载 时间:2016-09-30 我要评论

这篇文章主要介绍了thinkphp在php7环境下提示Cannot use ‘String’ as class name as it is reserved的解决方法,涉及thinkPHP针对php7关键字判定的相关底层代码修改技巧,需要的朋友可以参考下

本文实例讲述了thinkphp在php7环境下提示Cannot use ‘String' as class name as it is reserved的解决方法。分享给大家供大家参考,具体如下:

我有一网站之前用php7运行thinkphp没有什么问题,但是最近发现开启验证码的时候发现有错误

Cannot use 'String' as class name as it is reserved

在google baidu搜索了一下还是没有解决方法

于是自己动手解决,看来我是第一个分享出来的人

原因:

有一个类用了string类名,php7把String定为关键字

解决方法:

文件ThinkPHP\Library\Org\Util\Image.class.php

找到:

import('ORG.Util.String');
$code = String::rand_string($length, 4);

修改成:

import('ORG.Util.Stringnew');
$code = Stringnew::rand_string($length, 4);

复制文件:

ThinkPHP\Library\Org\Util\String.class.php

保存成:

ThinkPHP\Library\Org\Util\Stringnew.class.php

打开Stringnew.class.php:

class String {

修改成:

class Stringnew {

放上去验证码出来了,我搜索了一下没有其他地方引用,这个问题解决了

-------------------------------


3 datatype 改成 mysqli

'datatype'=>'mysqli'



http://www.niftyadmin.cn/n/681365.html

相关文章

编程随笔-ElasticSearch知识导图(3):映射

1. 啥是映射 ES中的映射(Mapping)实质上就是对文档对象结构的定义&#xff0c;也即对文档中各元素的描述。在ES中定义映射&#xff0c;就如同定义XML文档的XML Schema。  ES中的映射定义了文档模式&#xff08;就如同在关系数据库中定义了关系模式&#xff09;&#xff0c;文…

oneinstack一键包Nginx php多版本共存配置全过程

oneinstack一键包Nginx php多版本共存配置全过程 2016-01-17 12:39 3285人阅读 评论(0) 收藏 举报 分类&#xff1a; 服务器操作相关&#xff08;10&#xff09; 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 oneinstack一键包地址&#xff1a…

thinkphp3.2 I('get.id') 在 ningx代理apache下面错误 GET POST参数都变成_URL_ 解决方法 I函数

thinkphp3.2 I(get.id) 在 ningx代理apache下面错误 GET POST参数都变成_URL_ 解决方法 I函数/*** 获取输入参数 支持过滤和默认值* 使用方法:* <code>* I(id,0); 获取id参数 自动判断get或者post* I(post.name,,htmlspecialchars); 获取$_POST[name]* I(get.); 获取$_G…

UML--面向对象还是面向过程

为什么使用面向对象&#xff0c;面向对象和面向过程有差别在哪里呢&#xff1f;面向过程和面向对象有什么小故事呢&#xff1f; 面向过程&#xff1a; 面向过程&#xff0c;就像他的名字一样针对过程&#xff0c;它认为世界是一个个互相联系的小系统组成的&#xff0c;有着因果…

UML-面向对象

面向对象的特征&#xff0c;说一哈我知道的&#xff0c;哈哈哈 抽象 相似本质 抽象层次 什么是抽象层次呢&#xff0c;其实很简单&#xff0c;就相当于你在不同的层次上面进行分析 封装 啥是封装&#xff1f;举个例子&#xff0c;我们将对象看作一个盒子&#xff0c;除了与外…

http强制升级为https http头文件 Content Security Policy: 升级不安全的请求

http强制升级为https <meta http-equiv"Content-Security-Policy" content"upgrade-insecure-requests" />Content Security Policy: 升级不安全的请求“http://talk.f1host.cn/ApiEfl/getjsinfo?course_id325304”至使用“https”--------------…

UML--如何解决面向对象的困难

需要解决的问题 - 就是现实怎么映射到对象&#xff1f; - 对象又如何描述显示呢&#xff1f; - 对象对于现实的描述又是否准确呢&#xff1f; 现实如何映射到对象 &#xff08;现实–业务模式&#xff09; 建模 通过建模的方式将现实映射到对象世界中。 什么是建模&#xff…

Linux Redis 高可用之主从复制

Redis主从复制简介 和MySQL主从复制的原因一样&#xff0c;Redis虽然读取写入的速度都特别快&#xff0c;但是也会产生读压力特别大的情况。为了分担读压力&#xff0c;Redis支持主从复制&#xff0c;Redis的主从结构可以采用一主多从或者级联结构&#xff0c;Redis主从复制可以…