php中回调函数和匿名函数

php中回调函数和匿名函数

回调函数、闭包在JS中并不陌生,JS使用它可以完成事件机制,进行许多复杂的操作。根据作用不同分为回调和匿名。

一、回调函数

就是将后续的操作交给用户来定义,比如js中的点击事件:

$('button').on('click', function(){
	// ...
})
内核帮你注册了一个点击事件,点击完后要做什么则叫做回调,在php中也是一样的道理。
回调函数的参数也是由主程序定义好的并传递回来的,用户应该遵守。
定义
	class swoole{
		public function push($data, $func){
			// 主要业务
			....
			$a = ...;
			$b = ...;
			$c = ...;

			// 执行回调
			call_user_func_array($func, [$a, $b, $c]);
		}
	}

调用
	$swoole = new swoole();
	$swoole->push($data, function($a, $b, $c) use($d) {
		....
	});

	用户可以定义回调函数的业务逻辑,同样可以是use来引入外部参数使用。


二、匿名函数

匿名函数,顾名思义,是没有一个确定函数名的函数,PHP将匿名函数和闭包视作相同的概念(匿名函数在PHP中也叫作闭包函数)。它的用法,当然只能被当作变量来使用了。

定义
	function test($name, $age, $callback){
	    return $callback($name, $age);

	    //或者,如果有参数
	    //return call_user_func_array($callback, [$name, $age]);
	}

	$a = 'rao';
	$b = 123;
	echo test($a, $b, function($x, $y){
	    return 'name:'.$x.', age:'.$y;
	});

	或者
	$func = function($x, $y){
	    return 'name:'.$x.', age:'.$y;
	};
	echo test($a, $b, $func);

	或者
	function func($x, $y){
		return 'name:'.$x.', age:'.$y;
	}
	echo test($a, $b, 'func');

	通常在定义test的时候,闭包函数是不传参数的,需要用的参数都是由test函数来传,由闭包来使用,当然具体业务逻辑是由test和闭包来共同完成的,就比如 array_map($callback, $array), 

	$callback = function($val){
        doSomething($val);
    }

    function array_map($callback, $array){
	    $result = [];
		foreach($vars as $key=>$val){
		    $item = callback($val);
		    $result[] = $item;
		}
		return $result;
    }

	正常情况下,函数体内是无法调用外部的定义的变量的,需要通过参数传入到函数内部,作为闭包函数可以使用use关键字方便的将参数传递到函数体内部,多个参数通过逗号隔开
	$n = 'rao';
	echo test($n, function() use($n) {
	    return $n;
	});

	$n = 'rao';
	$b = '123';
	echo test($n, function() use($n, $b) {
	    return $n.'-'.$b;
	});

	需要注意的是$n,$b等变量需要在定义闭包函数之前定义,因为这个继承行为是在定义的时候产生的,而不是在调用时候产生的。也就是说传入闭包的值$n,$b的值在此刻就固定了,进入闭包体内后这两个变量的值就不会被外界干扰,内部的改变也不会影响外部的值,遵循函数体内局部变量的规则,例如:
	$n = 'rao';
	$b = '123';
	$func = function() use($n, $b) {
	    return $n.'-'.$b;
	};
	$n = 'rao22';
	$b = '12322';
	echo test($n, $func); // rao-123
	
	在匿名函数的use中如果使用引用传值,那么匿名函数中对参数值的改变会同样影响外部相应变量。
	$n = 'rao';
	echo test($n, function() use(&$n) {
	    $n = 'asd';
	    return $n;
	});
	echo "\n";
	echo $n; // asd

	那么是不是任何情况下,想通过匿名函数改变外部变量值都一定要通过引用方式向use传值呢?
	显然不是,我们知道,当函数的参数为对象时,那么,不需要使用引用,在函数体内部改变了对象,那么这个对象就是被改变了。
	所以,此处同样成立。那么,对于对象变量,加不加引用由什么区别呢,区别是:
	1、加了引用后,对象变量在函数后定义也是可以的。
	2、加了引用后,非对象变量在函数后定义不行。
	3、不加引用,所有变量都需要在函数前面定义。

	在类里面的匿名函数中$this依然表示该类的对象,直接使用即可,不需要use。

	class C{
	    protected $_num = 0;

	    public function mkFunc(){
	        $func = function(){
	            echo $this->_num++, "\n";
	        };

	        return $func;
	    }

	    public function get(){
	        echo $this->_num,"\n";
	    }
	}

你可能感兴趣的:(PHP)