preg_replace_callback()调用类中的回调函数
最近项目中使用preg_replace_callback,需要使用它执行正则匹配时回调类中的方法,需要有一些注意的地方,做个记录。
PHP文档中这样介绍 preg_replace_callback:(PHP 4 >= 4.0.5, PHP 5中可以使用),该方法用回调函数执行正则表达式的搜索和替换,本函数的行为几乎和 preg_replace() 一样,除了不是提供一个 replacement 参数,而是指定一个 callback 函数。该函数将以目标字符串中的匹配数组作为输入参数,并返回用于替换的字符串。
所以,我们可以这样使用这个函数,下面是PHP手册中的例子:
// 此文本是用于 2002 年的, // 现在想使其能用于 2003 年 $text = "April fools day is 04/01/2002/n"; $text.= "Last christmas was 12/24/2001/n"; // 回调函数 function next_year($matches) { // 通常:$matches[0] 是完整的匹配项 // $matches[1] 是第一个括号中的子模式的匹配项 // 以此类推 return $matches[1].($matches[2]+1); } echo preg_replace_callback( "|(/d{2}//d{2}/)(/d{4})|", "next_year", $text); // 结果为: // April fools day is 04/01/2003 // Last christmas was 12/24/2002 // 此文本是用于 2002 年的, // 现在想使其能用于 2003 年 $text = "April fools day is 04/01/2002/n"; $text.= "Last christmas was 12/24/2001/n"; // 回调函数 function next_year($matches) { // 通常:$matches[0] 是完整的匹配项 // $matches[1] 是第一个括号中的子模式的匹配项 // 以此类推 return $matches[1].($matches[2]+1); } echo preg_replace_callback( "|(/d{2}//d{2}/)(/d{4})|", "next_year", $text); // 结果为: // April fools day is 04/01/2003 // Last christmas was 12/24/2002
这么使用的确没有问题。
但是如果像下面那样在类中调用,就会报错。
//此文本是用于 2002 年的, //现在想使其能用于 2003 年 $text = "April fools day is 04/01/2002n"; $text.= "Last christmas was 12/24/2001n"; class ParseDate { // 回调函数 function next_year($matches) { // 通常:$matches[0] 是完整的匹配项 // $matches[1] 是第一个括号中的子模式的匹配项 // 以此类推 return $matches[1].($matches[2]+1); } function displayText($text) { echo preg_replace_callback( "|(d{2}/d{2}/)(d{4})|", "$this->next_year", $text); } } $pt = new ParseText(); $pt->displayText($text); //此文本是用于 2002 年的, //现在想使其能用于 2003 年 $text = "April fools day is 04/01/2002n"; $text.= "Last christmas was 12/24/2001n"; class ParseDate { // 回调函数 function next_year($matches) { // 通常:$matches[0] 是完整的匹配项 // $matches[1] 是第一个括号中的子模式的匹配项 // 以此类推 return $matches[1].($matches[2]+1); } function displayText($text) { echo preg_replace_callback( "|(d{2}/d{2}/)(d{4})|", "$this->next_year", $text); } } $pt = new ParseText(); $pt->displayText($text);
上 面的程序执行的结果会是 preg_replace_callback() requires argument 2, […],to be a valid callback 。为什么会这样?让我们再看一次PHP文档对于preg_replace_callback()函数的定义:
mixed preg_replace_callback ( mixed pattern, callback callback, mixed subject [, int limit] )本贴由FastMVC首发,谢谢关注FastMVC。
仔细看第二个参数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(”|(d{2}/d{2}/)(d{4})|”,array( &$this, ‘next_year’), $text);
就应该可以正常运行了。下面是完整的代码。
view plaincopy to clipboardprint?
// 此文本是用于 2002 年的, // 现在想使其能用于 2003 年 $text = "April fools day is 04/01/2002n"; $text.= "Last christmas was 12/24/2001n"; class ParseDate { // 回调函数 function next_year($matches) { // 通常:$matches[0] 是完整的匹配项 // $matches[1] 是第一个括号中的子模式的匹配项 // 以此类推 return $matches[1].($matches[2]+1); } function displayText($text) { echo preg_replace_callback( "|(d{2}/d{2}/)(d{4})|", array( &$this, 'next_year'), $text); } } $pt = new ParseText(); $pt->displayText($text);
1320