浏览: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'