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

最近项目中使用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); 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值