php 回调函数 this,PHP 中回调函数是全局的或是类实例时不同写法

PHP 像 JavaScript 一样,很方便使用回调函数,函数名就像一个普通的变量名一样可作为其他函数的参数,即成为一个让宿主函数调用的回调函数。但回调函数的用法依据回调函数是否是全局函数还是一个类中的函数是有区别的。比如 PHP 的preg_replace_callback — 用回调函数执行正则表达式的搜索和替换函数可以接受一个回调函数,我们来看这种区别。

如果是全局的回调函数,那容易,只要写上函数名作为字符串的形式传入就行的,看:

/**@author Unmi*/

function inverse($matches) {

return $matches[2].":".$matches[1];

}

$text = preg_replace_callback ("/(\d{7}):(.+)/", 'inverse' , '1125535:fantasia@sina.com');

echo $text;    //Output result: fantasia@sina.com:1125535

1

2

3

4

5

6

7

/**@author Unmi*/

functioninverse($matches){

return$matches[2].":".$matches[1];

}

$text=preg_replace_callback("/(\d{7}):(.+)/",'inverse','1125535:fantasia@sina.com');

echo$text;   //Output result: fantasia@sina.com:1125535

而如果 preg_replace_callback 函数是在类成员函数中被调用,同时 inverse 回调函数也是该类的成员函数,写法就不一样了。要是仍然写成下面这种方式的话:

/**@author Unmi*/

class ReplaceClass{

function inverse($matches) {

return $matches[2].':'.$matches[1];

}

function replace($src_str){

$text = preg_replace_callback ("/(.+?):(.+)/", 'inverse', $src_str);

return $text;

}

}

$rc = new ReplaceClass();

echo $rc->replace('Unmi:fantasia@sina.com');

1

2

3

4

5

6

7

8

9

10

11

12

13

14

/**@author Unmi*/

classReplaceClass{

functioninverse($matches){

return$matches[2].':'.$matches[1];

}

functionreplace($src_str){

$text=preg_replace_callback("/(.+?):(.+)/",'inverse',$src_str);

return$text;

}

}

$rc=newReplaceClass();

echo$rc->replace('Unmi:fantasia@sina.com');

你将会被提示:Warning: preg_replace_callback(): Requires argument 2, 'inverse', to be a valid callback,也就是找不到类里的这个 inverse() 方法,除非在类外部有一个全局的 inverse() 方法。但总是存在把回调函数写到类里的必要性的,这时候必须清楚的指明这个回调函数是属于哪个类或是实例的。

PHP 像 C++  一样的方式指写类成员函数,如果给 ReplaceClass 类的 inverse() 函数加个 static 关键字,是否能用

$text = preg_replace_callback("/(.+?):(.+)/", 'ReplaceClass::inverse', $src_str) 呢?没错,确实可以这样写,就是要注意此时的回调函数一定要有 static 修饰,是个静态函数(方法)。当然 inverse 也可是其他类的成员函数,那么就是 'AnotherClass::inverse',此时 inverse 必须是非 private 的。

除此之外,还可以用另外一种办法,就是在 'inverse' 参数位置上代之以数组,数组的第一个元素指明回调函数从哪里来,第二个元素指定回调函数名。可使用的两种形式是:

//第一种写法

$text = preg_replace_callback ("/(.+?):(.+)/", array($this,'inverse'), $src_str);

//第二种写法,如果 inverse 函数是声明在 InverseHome 类中的

$inverse_home = new InverseHome();

$text = preg_replace_callback ("/(.+?):(.+)/", array($inverse_home,'inverse'), $src_str);

//第三种写法

$text = preg_replace_callback ("/(.+?):(.+)/", array('ReplaceClass','inverse'), $src_str);

1

2

3

4

5

6

7

8

9

//第一种写法

$text=preg_replace_callback("/(.+?):(.+)/",array($this,'inverse'),$src_str);

//第二种写法,如果 inverse 函数是声明在 InverseHome 类中的

$inverse_home=newInverseHome();

$text=preg_replace_callback("/(.+?):(.+)/",array($inverse_home,'inverse'),$src_str);

//第三种写法

$text=preg_replace_callback("/(.+?):(.+)/",array('ReplaceClass','inverse'),$src_str);

可能蒙其他较为规范的面向对象语方的影响,你会认为第一、二种写法时,inverse() 函数必须非静态的,作为实例成员;而第二种用法时,inverse() 函数必须是静态的,是一个类成员。可是套用到这里就有些牵强,实际上 PHP 对 inverse() 函数是否为静态没有任何要求的。只是要受到 inverse() 函数是否为 private 的限制,如果 inverse() 函数是 private 的,第二、三种写法是不合法的。

理解了上面的回调函数所处位置的用法要求时,如果在 WordPress 的源代码看到下面这样的代码时:

add_action('init', array($custom_url_rewriter,'redirect'), 1);

就不会觉得奇怪了,这里的回调函数是定义在实例 $custom_url_rewriter 所在类中,且是非 private 的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值