七零部落格
思则大道至简,疑则谜团重重!
思则大道至简,疑则谜团重重!
怎样妙用preg_replace_callback函数呢?下面就有达内的老是来为学员们介绍一下:
今天在迁移discuz数据的时候我们发现帖子里的content字段经常会有[attach]78[/attach]下面这些题选什么,为什么?
这样用[attach]的标签包括起来的数字,发现这个数字是代表这个帖子内容的附件的id,我们现在不需要找一个[attach]这个标签的内容了。需
要把他替换掉。
首先想到的使用正则把这样的数据替换成其他字符串例如“请查看附件”。想使用preg_replace
来替换,这个也能达到目的。但是后来我们有发现有些content字段里的内容他不只一对[attach]标签,有的有好几对[attach]标签,表示
他有多个附件。接着用上面的preg_replace这个方法替换发现原content里有几对[attach]标签,替换后的结果就有几句“请查看附
件”这样的字符串。这感觉非常不友好。想实现的结果,如果有多对[attach]标签,那么就替换一对为“请查看附件”,其他的都替换为空就行了。
看会下php手册发现了这个函数preg_replace_callback,这个函数的行为除了
可以指定一个callback替代replacement进行替换 字符串的计算, 其他方面等同于preg_replace()
。我们要的就是他的回调函数callback,这里我们可以进行自定义设置。下面举例子吧
0) { $con =
''; }else{ $con = " 请查看附件 "; } $count++; return $con; } $result =
preg_replace_callback($pat, replace_fn, $content); var_dump($result);
?> 这样结果就是我们想要的了。 string(38) " 请查看附件 下面这些题选什么,为什么?"。
但是我们现在开发一般是把代码写在类里。例如
class ParseDate { // 回调函数 function replace_fn($matches)
{ global $count; if ($count > 0) { $con = ''; }else{ $con =
" 请查看附件 "; } $count++; return $con; } function
displayText($text) { echo preg_replace_callback(
"/[attach](d+)[/attach]/",
"$this->replace_fn", $text); } } $pt = new
ParseText(); $pt->displayText($text);
这样写运行后你会发现报错了:preg_replace_callback(): Requires argument 2, '', to be a valid callback in...
为什么会这样?让我们再看一次PHP文档对于preg_replace_callback()函数的定义:
mixed preg_replace_callback ( mixed pattern, callback callback, mixed subject [, int limit] )
仔细看第二个参数callback,并不是字符串类型,而是callback这个伪类型!看看PHP的文档是怎么定义callback这个伪类型的:
callback:
有些诸如 call_user_function() 或 usort() 的函数接受用户自定义的函数作为一个参数。Callback 函数不仅可以是一个简单的函数,它还可以是一个对象的方法,包括静态类的方法。
一个 PHP 函数用函数名字符串来传递。可以传递任何内置的或者用户自定义的函数,除了 array(),echo(),empty(),eval(),exit(),isset(),list(),print() 和 unset()。
一个对象的方法以数组的形式来传递,数组的下标 0 指明对象名,下标 1 指明方法名。
对于没有实例化为对象的静态类,要传递其方法,将数组 0 下标指明的对象名换成该类的名称即可。
如果是要调用对象的方法函数,那么就要用数组的形式来传递。在上面的程序段中,我们错误的想当然的使用了字符串的形式,所以导致PHP无法找到我们想要使用的回调函数。
知道了原因,就好办了,只要简单的把代码改成
preg_replace_callback(”/[attach](d+)[/attach]/”,array( &$this, ‘replace_fn’), $text);