升级了Mac新系统Yosemite,用着非常舒服,不过每次Mac系统更新,php和apache都要重新折腾一下,这次php的版本从5.4更新到5.5。。。

工作中对一些开源php软件进行二次开发,升级以后软件报错:

preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead

在网上查找原因,函数preg_replace的“/e”修饰符在5.5的版本中已经被弃用,要使用preg_replace_callback() 代替。

“/e”的作用官方说明如下:当使用被弃用的 e 修饰符时, 这个函数会转义一些字符(即:'、"、 \ 和 NULL)然后进行后向引用替换。当这些完成后请确保后向引用解析完后没有单引号或 双引号引起的语法错误(比如: 'strlen(\'$1\')+strlen("$2")')。确保符合PHP的字符串语法,并且符合eval语法。因为在完成替换后,引擎会将结果字符串作为php代码使用eval方式进行评估并将返回值作为最终参与替换的字符串。

根据实际使用的情况我理解这个的作用是,使用preg_replace和修饰符以后,字符串被替换为包含了可执行的php代码,

举个栗子:

$html="<h6>HelloWorld</h6>";echo$html;echopreg_replace('(<h([1-6])>(.*?)</h\1>)e','"<h$1>".strtoupper("$2")."</h$1>"',$html);

字符被替换的同时也执行strtoupper函数。其实感觉这种用法怪怪的。。。

其实要我写我会写成

if(preg_match('(<h([1-6])>(.*?)</h\1>)',$html,$m)){

echo"<h{$m[1]}>".strtoupper($m[2]) ."</h{$m[1]}>";

}

这样更容易读懂。。。

下面说说 preg_replace_callback,它替代了preg_replace的“/e”修饰符,不过用起来也很怪。。。

echopreg_replace_callback('(<h([1-6])>(.*?)</h\1>)',function($m){return"<h$m[1]>".strtoupper($m[2])."</h$m[1]>";},$html);

执行一个正则表达式搜索并且使用一个回调进行替换,其实和preg_match匹配有点像。

解释完preg_replace_callback这个函数看看实际中解决问题。

以下代码现在开源软件的模板引擎好像很多都用到了,

preg_replace("/{([^\}\{\n]*)}/e","\$this->select('\\1');",$source);

改成

preg_replace_callback("/{([^\}\{\n]*)}/",function($m){return$this->select($m[1]);},$source);

下面这段数组替换没想到更好的方法

$pattern=array('/<!--[^>|\n]*?({.+?})[^<|{|\n]*?-->/',//替换smarty注释'/<!--[^<|>|{|\n]*?-->/',//替换不换行的html注释'/(href=["|\'])\.\.\/(.*?)(["|\'])/i',//替换相对链接'/((?:background|src)\s*=\s*["|\'])(?:\.\/|\.\.\/)?(p_w_picpaths\/.*?["|\'])/is',//在p_w_picpaths前加上$tmp_dir'/((?:background|background-p_w_picpath):\s*?url\()(?:\.\/|\.\.\/)?(p_w_picpaths\/)/is',//在p_w_picpaths前加上$tmp_dir'/{nocache}(.+?){\/nocache}/ise',//无缓存模块);$replace=array('\1','','\1\2\3','\1'.$tmp_dir.'\2','\1'.$tmp_dir.'\2',"'{insertname=\"nocache\"'.'".$this->_echash."'.base64_encode('\\1').'}'",);preg_replace($pattern,$replace,$source);


只想到分步进行替换

$pattern=array('/<!--[^>|\n]*?({.+?})[^<|{|\n]*?-->/',//替换smarty注释'/<!--[^<|>|{|\n]*?-->/',//替换不换行的html注释'/(href=["|\'])\.\.\/(.*?)(["|\'])/i',//替换相对链接'/((?:background|src)\s*=\s*["|\'])(?:\.\/|\.\.\/)?(p_w_picpaths\/.*?["|\'])/is',//在p_w_picpaths前加上$tmp_dir'/((?:background|background-p_w_picpath):\s*?url\()(?:\.\/|\.\.\/)?(p_w_picpaths\/)/is',//在p_w_picpaths前加上$tmp_dir//'/{nocache}(.+?){\/nocache}/ise',//无缓存模块);$replace=array('\1','','\1\2\3','\1'.$tmp_dir.'\2','\1'.$tmp_dir.'\2',//"'{insertname=\"nocache\"'.'".$this->_echash."'.base64_encode('\\1').'}'",);//preg_replace($pattern,$replace,$source);###php5.5preg_replace不能使用\e参数$source=preg_replace($pattern,$replace,$source);preg_replace_callback('/{nocache}(.+?){\/nocache}/is',function($m){return'{insertname=\"nocache\"'.$this->_echash.base64_encode($m[1]).'}';},$source);}