preg_replace_callback()调用类中的回调函数

来源:互联网 发布:nginx.org set 编辑:程序博客网 时间:2024/05/22 11:56

最近项目中使用preg_replace_callback,需要使用它执行正则匹配时回调类中的方法,需要有一些注意的地方,做个记录。PHP文档中这样介绍 preg_replace_callback:(PHP 4 >= 4.0.5, PHP 5中可以使用),该方法用回调函数执行正则表达式的搜索和替换,本函数的行为几乎和 preg_replace() 一样,除了不是提供一个 replacement 参数,而是指定一个 callback 函数。该函数将以目标字符串中的匹配数组作为输入参数,并返回用于替换的字符串。

所以,我们可以这样使用这个函数,下面是PHP手册中的例子:

view plaincopy to clipboardprint?

  1. // 此文本是用于 2002 年的,
  2. // 现在想使其能用于 2003 年
  3. $text = "April fools day is 04/01/2002/n"; 
  4. $text.= "Last christmas was 12/24/2001/n"; 
  5. // 回调函数
  6. function next_year($matches) { 
  7. // 通常:$matches[0] 是完整的匹配项
  8. // $matches[1] 是第一个括号中的子模式的匹配项
  9. // 以此类推
  10. return $matches[1].($matches[2]+1); 
  11. echo preg_replace_callback( 
  12. "|(/d{2}//d{2}/)(/d{4})|", 
  13. "next_year", 
  14. $text); 
  15. // 结果为:
  16. // April fools day is 04/01/2003
  17. // 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

这么使用的确没有问题。

但是如果像下面那样在类中调用,就会报错。

view plaincopy to clipboardprint?

  1. //此文本是用于 2002 年的,
  2. //现在想使其能用于 2003 年
  3. $text = "April fools day is 04/01/2002n"; 
  4. $text.= "Last christmas was 12/24/2001n"; 
  5. class ParseDate { 
  6. // 回调函数
  7. function next_year($matches) { 
  8. // 通常:$matches[0] 是完整的匹配项
  9. // $matches[1] 是第一个括号中的子模式的匹配项
  10. // 以此类推
  11. return $matches[1].($matches[2]+1); 
  12.     } 
  13. function displayText($text) { 
  14. echo preg_replace_callback( 
  15. "|(d{2}/d{2}/)(d{4})|", 
  16. "$this->next_year", 
  17. $text); 
  18.     } 
  19. $pt = new ParseText(); 
  20. $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] )

仔细看第二个参数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?

  1. // 此文本是用于 2002 年的,
  2. // 现在想使其能用于 2003 年
  3. $text = "April fools day is 04/01/2002n"; 
  4. $text.= "Last christmas was 12/24/2001n"; 
  5. class ParseDate { 
  6. // 回调函数
  7. function next_year($matches) { 
  8. // 通常:$matches[0] 是完整的匹配项
  9. // $matches[1] 是第一个括号中的子模式的匹配项
  10. // 以此类推
  11. return $matches[1].($matches[2]+1); 
  12.     } 
  13. function displayText($text) { 
  14. echo preg_replace_callback( 
  15. "|(d{2}/d{2}/)(d{4})|", 
  16. array( &$this, 'next_year'), 
  17. $text); 
  18.     } 
  19. $pt = new ParseText(); 
  20. $pt->displayText($text); 
原创粉丝点击