浅谈PHP闭包 Closure和Callable

Closure 必须是匿名函数,  callable 同时还可以为可调用函数名

  1. function func1(callable $callable)
  2. {
  3. return $callable();
  4. }
  5. function func2(Closure $closure)
  6. {
  7. return $closure();
  8. }
  9. function test()
  10. {
  11. echo "test\n";
  12. }
  13. $demo = function (){
  14. echo 'demo';
  15. };
  16. func1('test'); //输出 test
  17. func1($demo);//输出demo
  18. //报错 Fatal error: Uncaught TypeError: func2(): Argument #1 ($closure) must be of type Closure, string given, called
  19. func2('test');
  20. func2($demo);//输出demo

 

  1. <?php
  2. function func1(callable $callable)
  3. {
  4. return $callable();
  5. }
  6. function func2(Closure $closure)
  7. {
  8. return $closure();
  9. }
  10. function test()
  11. {
  12. echo "test\n";
  13. }
  14. $demo = function (){
  15. echo 'demo';
  16. };
  17. //报错 Fatal error: Uncaught TypeError: func2(): Argument #1 ($closure) must be of type Closure, string given, called
  18. func2('test');
  19. func2(Closure::fromCallable('test'));//输出 test
  1. /**
  2. * 声明一个a类
  3. */
  4. class a{
  5. /**
  6. * @var int 这里声明一个a成员变量 初始值为1
  7. */
  8. public $a = 1;
  9. }
  10. //这里声明一个闭包函数 函数输出this指向a变量
  11. $closure = function (){
  12. echo $this->a;
  13. $this->a = 3;
  14. };
  15. $a = new a; //实例化a类
  16. //调用闭包中的bindTo方法,将闭包函数内的this指向到实例a
  17. $closure = $closure->bindTo($a);
  18. //执行闭包
  19. $closure();//输出1
  20. var_dump($a->a);//输出3
  1. /**
  2. * 声明一个a类
  3. */
  4. class a{
  5. /**
  6. * @var int 这里声明一个a成员变量 初始值为1
  7. */
  8. public $a = 1;
  9. protected $b=2;
  10. private $c = 3;
  11. public function a()
  12. {
  13. echo $this->a;
  14. }
  15. protected function b()
  16. {
  17. echo $this->b;
  18. }
  19. private function c()
  20. {
  21. echo $this->c;
  22. }
  23. }
  24. //这里声明一个闭包函数 函数输出this指向a变量
  25. $closure = function (){
  26. echo $this->a;//输出1
  27. echo $this->b;//报错 Fatal error: Uncaught Error: Cannot access protected property a::$b
  28. echo $this->c;//报错 Fatal error: Uncaught Error: Cannot access private property a::$c
  29. echo $this->a();//输出1
  30. echo $this->b();//报错 Fatal error: Uncaught Error: Call to protected method a::b() from scope Closure
  31. echo $this->c();//报错 Fatal error: Uncaught Error: Call to private method a::c() from scope Closure
  32. };
  33. $a = new a; //实例化a类
  34. //调用闭包中的bindTo方法,将闭包函数内的this指向到实例a
  35. $closure = $closure->bindTo($a);
  36. //执行闭包
  37. $closure();
  1. $closure = $closure->bindTo($a,'a');

这个时候再执行上面的代码

  1. /**
  2. * 声明一个a类
  3. */
  4. class a{
  5. /**
  6. * @var int 这里声明一个a成员变量 初始值为1
  7. */
  8. public $a = 1;
  9. protected $b=2;
  10. private $c = 3;
  11. public function a()
  12. {
  13. echo $this->a;
  14. }
  15. protected function b()
  16. {
  17. echo $this->b;
  18. }
  19. private function c()
  20. {
  21. echo $this->c;
  22. }
  23. }
  24. //这里声明一个闭包函数 函数输出this指向a变量
  25. $closure = function (){
  26. echo $this->a;//输出1
  27. echo $this->b;//输出2
  28. echo $this->c;//输出3
  29. $this->a();//输出1
  30. $this->b();//输出2
  31. $this->c();//输出3
  32. };
  33. $a = new a; //实例化a类
  34. //调用闭包中的bindTo方法,将闭包函数内的this指向到实例a
  35. $closure = $closure->bindTo($a,'a');
  36. //执行闭包
  37. $closure();
  1. $closure = Closure::bind($closure,$a,'a');

执行效果和上面的bindTo方法结果一样

  1. /**
  2. * 声明一个a类
  3. */
  4. class a{
  5. /**
  6. * @var int 这里声明一个a成员变量 初始值为1
  7. */
  8. public $a = 1;
  9. protected $b=2;
  10. private $c = 3;
  11. public function a()
  12. {
  13. echo $this->a;
  14. }
  15. protected function b()
  16. {
  17. echo $this->b;
  18. }
  19. private function c()
  20. {
  21. echo $this->c;
  22. }
  23. public static function t()
  24. {
  25. }
  26. }
  27. function test()
  28. {
  29. };
  30. $a = new a;
  31. is_callable('test');//True
  32. is_callable(function (){});//True
  33. is_callable([$a,'a']);//True
  34. is_callable(['a','t']);//True
  1. /**
  2. * 声明一个a类
  3. */
  4. class a{
  5. /**
  6. * @var int 这里声明一个a成员变量 初始值为1
  7. */
  8. public $a = 1;
  9. protected $b=2;
  10. private $c = 3;
  11. public function a()
  12. {
  13. echo $this->a;
  14. }
  15. protected function b()
  16. {
  17. echo $this->b;
  18. }
  19. private function c()
  20. {
  21. echo $this->c;
  22. }
  23. public static function t()
  24. {
  25. echo 1;
  26. }
  27. }
  28. function test()
  29. {
  30. echo 'test';
  31. };
  32. $a = new a;
  33. $closure = Closure::fromCallable('test');
  34. $closure();//输出test
  35. $closure = Closure::fromCallable(['a','t']);
  36. $closure();//输出1
  37. $closure = Closure::fromCallable([$a,'a']);
  38. $closure();//输出1