ThinkPHP3.1迁移到PHP7的注意事项,thinkphp3.1php7
阅读前请先移步http://blog.csdn.net/lankecms/article/details/78090678,文本是做相应的补充。
最近项目从PHP5.5升级到了PHP7.0,框架是ThinkPHP3.1.3,记录下升级过程。
一、我用的apache服务器,项目里开启了路由功能,所以.htaccess文件就改成了
<IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php?s=$1 [QSA,PT,L] </IfModule>二、在PHP7中,preg_replace不能用/e修饰符,所以用preg_replace_callback代替preg_replace,
需要修改的文件包括
ThinkPHP\Lib\Template\ThinkTemplate.class.php
ThinkPHP\Lib\Core\Dispatcher.class.php
ThinkPHP\Lib\Core\Db.class.php
ThinkPHP\Lib\Behavior\CheckRouteBehavior.class.php
ThinkPHP\Extend\Mode\Lite\Dispatcher.class.php
1)ThinkPHP\Lib\Template\ThinkTemplate.class.php
这个文件大约需要修改8处地方
NO1. 大约在137行,将
$tmplContent = preg_replace('/<!--###literal(\d+)###-->/eis',"\$this->restoreLiteral('\\1')",$tmplContent);替换为
$tmplContent = preg_replace_callback('/<!--###literal(\d+)###-->/is', function($r) { return $this->restoreLiteral($r[1]); }, $tmplContent);
NO2. 大约在168行,将
$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($r) { return $this->parseLiteral($r[1]); }, $content);
NO3. 大约在197行,将
$content = preg_replace('/('.$this->config['tmpl_begin'].')([^\d\s'.$this->config['tmpl_begin'].$this->config['tmpl_end'].'].+?)('.$this->config['tmpl_end'].')/eis',"\$this->parseTag('\\2')",$content);替换为
$content = preg_replace_callback('/(' . $this->config['tmpl_begin'] . ')([^\d\s' . $this->config['tmpl_begin'] . $this->config['tmpl_end'] . '].+?)(' . $this->config['tmpl_end'] . ')/is', function($r) { return $this->parseTag($r[2]); }, $content);
NO4. 大约在266行,将
preg_replace('/'.$begin.'block\sname=(.+?)\s*?'.$end.'(.*?)'.$begin.'\/block'.$end.'/eis',"\$this->parseBlock('\\1','\\2')",$content);替换为
preg_replace_callback('/' . $begin . 'block\sname=(.+?)\s*?' . $end . '(.*?)' . $begin . '\/block' . $end . '/is', function ($r) { $this->parseBlock($r[1], $r[2]); }, $content);
NO5. 大约在271行,将
$content = preg_replace('/'.$begin.'block\sname=(.+?)\s*?'.$end.'(.*?)'.$begin.'\/block'.$end.'/eis',"\$this->replaceBlock('\\1','\\2')",$content);替换为
$content = preg_replace_callback('/' . $begin . 'block\sname=(.+?)\s*?' . $end . '(.*?)' . $begin . '\/block' . $end . '/is', function ($r) { return $this->replaceBlock($r[1], $r[2]); }, $content);
NO6. 大约在273行,将
$content = preg_replace('/'.$begin.'block\sname=(.+?)\s*?'.$end.'(.*?)'.$begin.'\/block'.$end.'/eis',"stripslashes('\\2')",$content);替换为
$content = preg_replace_callback('/' . $begin . 'block\sname=(.+?)\s*?' . $end . '(.*?)' . $begin . '\/block' . $end . '/is', function ($r) { return stripslashes($r[2]); }, $content);
NO7和NO8,这两处是连在一起的 大约在396行,改成如下:
if (!$closeTag){ $patterns = '/'.$begin.$parseTag.$n1.'\/(\s*?)'.$end.'/is'; $replacement = "\$this->parseXmlTag('$tagLib','$tag','$1','')"; $content = preg_replace_callback($patterns, function($r) use($tagLib, $tag) { return $this->parseXmlTag($tagLib, $tag, $r[1], ''); },$content); }else{ $patterns = '/'.$begin.$parseTag.$n1.$end.'(.*?)'.$begin.'\/'.$parseTag.'(\s*?)'.$end.'/is'; $replacement = "\$this->parseXmlTag('$tagLib','$tag','$1','$2')"; for($i=0;$i<$level;$i++) $content = preg_replace_callback($patterns, function($r) use($tagLib, $tag) { return $this->parseXmlTag($tagLib, $tag, $r[1], $r[2]); },$content); }
2)ThinkPHP\Lib\Core\Dispatcher.class.php
大约132行,将
preg_replace('@(\w+)\/([^\/]+)@e', '$var[\'\\1\']=strip_tags(\'\\2\');', implode('/',$paths));改为
preg_replace_callback('@(\w+)\/([^\/]+)@',function($r) use (&$var){ $var[$r['1']] = strip_tags($r[2]); },implode('/',$paths));
3)ThinkPHP\Lib\Core\Db.class.php
大约605行,将
$joinStr = preg_replace("/__([A-Z_-]+)__/esU",C("DB_PREFIX").".strtolower('$1')",$joinStr);改为
$DB_PREFIX = C("DB_PREFIX"); $joinStr = preg_replace_callback("/__([A-Z_-]+)__/sU",function ($r) use($DB_PREFIX) { return $DB_PREFIX.".strtolower({$r[1]})"; },$joinStr);
4)ThinkPHP\Lib\Behavior\CheckRouteBehavior.class.php
这个文件需要修改的地方共4处
NO1. 大约151行,将
$url = preg_replace('/:(\d+)/e','$values[\\1-1]',$url);改为
$url = preg_replace_callback('/:(\d+)/',function($r) use (&$values){ return $values[$r[1]-1]; },$url);NO2. 大约168行,将
preg_replace('@(\w+)\/([^\/]+)@e', '$var[strtolower(\'\\1\')]=strip_tags(\'\\2\');', implode('/',$paths));改为
preg_replace_callback('@(\w+)\/([^\/]+)@',function($r) use (&$var){ $var[strtolower($r['1'])] = strip_tags($r[2]); },implode('/',$paths));
NO3. 大约191行,将
$url = preg_replace('/:(\d+)/e','$matches[\\1]',$url);改为
$url = preg_replace_callback('/:(\d+)/', function($r) use (&$matches) { return $matches[$r[1]]; },$url);
NO4. 大约201行,将
preg_replace('@(\w+)\/([^,\/]+)@e', '$var[strtolower(\'\\1\')]=strip_tags(\'\\2\');', $regx);改为
preg_replace_callback('@(\w+)\/([^,\/]+)@',function($r) use (&$var){ $var[strtolower($r['1'])] = strip_tags($r[2]); },$regx);
5)ThinkPHP\Extend\Mode\Lite\Dispatcher.class.php
大约65行,将
$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));改为
preg_replace_callback('@(\w+)'.$depr.'([^'.$depr.'\/]+)@',function($r) use (&$var){ $var[$r['1']] = $r[2]; },implode($depr,$paths));
6)ThinkPHP\Lib\Behavior\ReadHtmlCacheBehavior.class.php
大约65行处的一个if判断替换为:
if(!empty($html)) { // 解读静态规则 $rule = $html[0]; // 以$_开头的系统变量 //$rule = preg_replace('/{\$(_\w+)\.(\w+)\|(\w+)}/e',"\\3(\$\\1['\\2'])",$rule); $rule = preg_replace_callback('/{\$(_\w+)\.(\w+)\|(\w+)}/',function($r){ $system = "$r[3](\${$r[1]}['$r[2]'])"; eval( "\$system = $system ;" ); return $system; },$rule); //$rule = preg_replace('/{\$(_\w+)\.(\w+)}/e',"\$\\1['\\2']",$rule); $rule = preg_replace_callback('/{\$(_\w+)\.(\w+)}/',function($r){ $system = "\${$r[1]}['$r[2]']"; eval( "\$system = $system ;" ); return $system; },$rule); // {ID|FUN} GET变量的简写 //$rule = preg_replace('/{(\w+)\|(\w+)}/e',"\\2(\$_GET['\\1'])",$rule); $rule = preg_replace_callback('/{(\w+)\|(\w+)}/',function($r){ return $r[2]($_GET[$r[1]]); },$rule); //$rule = preg_replace('/{(\w+)}/e',"\$_GET['\\1']",$rule); $rule = preg_replace_callback('/{(\w+)}/',function($r){ return $_GET[$r[1]]; },$rule); // 特殊系统变量 $rule = str_ireplace( array('{:app}','{:module}','{:action}','{:group}'), array(APP_NAME,MODULE_NAME,ACTION_NAME,defined('GROUP_NAME')?GROUP_NAME:''), $rule); // {|FUN} 单独使用函数 //$rule = preg_replace('/{\|(\w+)}/e',"\\1()",$rule); $rule = preg_replace_callback('/{\|(\w+)}/',function($r){ return $r[1](); },$rule); if(!empty($html[2])) $rule = $html[2]($rule); // 应用附加函数 $cacheTime = isset($html[1])?$html[1]:C('HTML_CACHE_TIME'); // 缓存有效期 // 当前缓存文件 define('HTML_FILE_NAME',HTML_PATH . $rule.C('HTML_FILE_SUFFIX')); return $cacheTime; }
四、如果有用到验证码,请把ThinkPHP\Extend\Library\ORG\Util目录下的String.class.php复制一份放在一起,并改名为Stringnew.class.php
打开Stringnew.class.php把所有的String::替换为Stringnew::
并把类名Class String 改为 Class Stringnew
打开ThinkPHP\Extend\Library\ORG\Util\Image.class.php,把所有的
import('ORG.Util.String');替换成
import('ORG.Util.Stringnew');
五、自定义函数的参数最好给定默认值,如果自定义函数规定了参数,但是没有指定默认值,在外部调用的时候,如果传参的时候少传值了,那么运行会报错!
PHP之友评论