Blogger Information
Blog 15
fans 0
comment 0
visits 10884
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
闭包与对象绑定和自定义异常类
Original
565 people have browsed it

bind()绑定方法

与public属性绑定

  1. namespace php\demo\part1;
  2. //空行
  3. //首先定义一个用来演示的类
  4. class Youth
  5. {
  6. public $name;
  7. public function show(){
  8. //非静态成员是通过this关键字和->结合来访问
  9. return $this->name.'是一名年轻人';
  10. }
  11. }
  12. //定义一个匿名函数,这个函数用来绑定youth类中的属性,用于设置类中属性的值,该函数接收1个$name参数
  13. $setValueFun = function ($name){
  14. //因为这个函数将要和类绑定,绑定后就像类中的一个方法,因此在代码中要用$this->name来访问类中的属性
  15. $this->name = $name;
  16. };
  17. //将Youth类实例出一个对象
  18. $obj = new Youth();
  19. //bind()是Closure类中的一个静态方法,其返回值是上面那个匿名函数的复制。
  20. //该方法第一个参数代表要准备和类绑定的匿名函数,也就是上面$setvalue代表的匿名函数。
  21. //该方法第二参数代表要绑定的类的一个实例
  22. //该方法第三个参数代表类作用域,在使用的时候就是用绑定类的类名,因为这段代码只是设置public属性,因此可以省略。
  23. //下面代码中在Closure前面加上'\'是使用的完全限定名称,代表全局命名空间,也可以用use Closure来代替
  24. $newSetValueFun = \Closure::bind($setValueFun,$obj);
  25. //还可以直接这么写,省略掉上面实例化的步骤
  26. //$newSetValueFun = Closure::bind($setValueFun,new Youth());
  27. //通过$newSetValueFun来给实例化出来的对象中的public属性$name赋值
  28. $newSetValueFun('Lucy');
  29. //调用Youth类中的show方法来验证
  30. echo $obj->show();
  31. //经验证最后输出:Lucy是一名年轻人
  32. private属性绑定(protected属性操作相同)
  33. //命名空间
  34. namespace php\demo\part1;
  35. use Closure;
  36. //空行
  37. //首先定义一个用来演示的类
  38. class Youth
  39. {
  40. private $weight;
  41. public function __toString(){
  42. //非静态成员是通过this关键字和->结合来访问,因此public和private属性访问方法相同
  43. return '一名年轻人的体重是'.$this->weight.'KG';
  44. }
  45. }
  46. //定义一个匿名函数,这个函数用来绑定youth类中的属性,用于设置类中属性的值,该函数接收2个参数
  47. $setValueFun = function ($weight){
  48. //因为这个函数将要和类绑定,绑定后就像类中已经定义的一个方法一样,因此在代码中要用$this->name来访问类中的属性
  49. $this->weight = $weight;
  50. };
  51. //将Youth类实例出一个对象
  52. $obj = new Youth();
  53. //bind()是Closure类中的一个静态方法,其返回值是上面那个匿名函数的复制。
  54. //该方法第一个参数代表要准备和类绑定的匿名函数,也就是上面$setvalue代表的匿名函数。
  55. //该方法第二参数代表要绑定的类的一个实例,换个角度看就是说匿名函数中的this代表哪个实例化的对象。
  56. //该方法第三个参数代表类作用域,在使用的时候就是用绑定类的类名。因为这里访问了类的私有成员,只有在其所在的类中才能被访问,因此必须指出类的作用域,不然就会报错。
  57. //因为使用了命名空间,而Youth作为Closure的参数,使用非限定名称会报错,应该使用完全限定或者限定名称
  58. $newSetValueFun = Closure::bind($setValueFun,$obj,'php\demo\part1\Youth');
  59. //还可以直接这么写,省略掉上面实例化的步骤
  60. //$newSetValueFun = Closure::bind($setValueFun,new Youth());
  61. //通过$newSetValueFun来给实例化出来的对象中的public属性$name赋值
  62. $newSetValueFun(45);
  63. //激活Youth类中的魔术方法__tostring()方法来验证
  64. echo $obj;
  65. //经验证最后输出:一名年轻人的体重是45KG

与static属性绑定

  1. namespace php\demo\part1;
  2. use Closure;
  3. //空行
  4. //首先定义一个用来演示的类
  5. class Youth
  6. {
  7. static $gender;
  8. public function __toString(){
  9. //非静态成员是通过this关键字和->结合来访问,因此public和private属性访问方法相同
  10. return '一名年轻人的性别是'.static::$gender;
  11. //另一种写法是
  12. //return '一名年轻人的性别是'.Youth::$gender;或者return '一名年轻人的性别是'.self::$gender
  13. }
  14. }
  15. //定义一个匿名函数,这个函数用来绑定youth类中的属性,用于设置类中属性的值,该函数接收1个参数
  16. $setValueFun = function ($gender){
  17. //因为这个函数将要和类绑定,绑定后就像类中已经定义的一个方法一样,在类中访问静态属性不能用$this,因为静态属性是所有对象共用的,只有一份,而$this代表具体的实例化对象
  18. static::$gender = $gender;
  19. };
  20. //bind()是Closure类中的一个静态方法,其返回值是上面那个匿名函数的复制。
  21. //该方法第一个参数代表要准备和类绑定的匿名函数,也就是上面$setvalue代表的匿名函数。
  22. //该方法第二参数代表要绑定的类的一个实例,换个角度看就是说匿名函数中的this代表哪个实例化的对象,因为这里访问的是静态成员,不需要实例化的对象,在这个地方可以用null。
  23. //该方法第三个参数代表类作用域,在使用的时候就是用绑定类的类名,在访问静态或者私有属性的时候必须加上这个参数。
  24. //因为使用了命名空间,而Youth作为Closure的参数,使用非限定名称会报错,应该使用完全限定或者限定名称
  25. $newSetValueFun = Closure::bind($setValueFun,null,Youth::class);
  26. //还可以直接这么写
  27. //$newSetValueFun = Closure::bind($setValueFun,null,'php\demo\part1\Youth');
  28. $newSetValueFun('female');
  29. //激活Youth类中的魔术方法__tostring()方法来验证
  30. $obj = new Youth();
  31. echo $obj;
  32. //经验证最后输出:一名年轻人的性别是female

同时访问public、private、protected和static属性,和一个public方法

  1. namespace php\demo\part1;
  2. use Closure;
  3. //空行
  4. //首先定义一个用来演示的类
  5. class Youth
  6. {
  7. public $name;
  8. static $gender;
  9. protected $age;
  10. private $weight;
  11. public function show(){
  12. //非静态成员是通过this关键字和->结合来访问,因此public和private属性访问方法相同
  13. return $this->name.'的性别是'.static::$gender.',今年'.$this->age.'岁,体重有'.$this->weight.'Kg';
  14. }
  15. }
  16. //定义一个匿名函数,这个函数用来绑定youth类中的属性,用于设置类中属性的值,该函数接收2个参数
  17. $setValueFun = function ($name,$gender,$age,$weight){
  18. //因为这个函数将要和类绑定,绑定后就像类中已经定义的一个方法一样,因此在代码中要用$this->name来访问类中的属性
  19. $this->weight = $weight;
  20. $this->age = $age;
  21. $this->name = $name;
  22. static::$gender = $gender;
  23. //通过闭包调用类中的方法
  24. echo $this->show();
  25. };
  26. //bind()是Closure类中的一个静态方法,其返回值是上面那个匿名函数的复制。
  27. //该方法第一个参数代表要准备和类绑定的匿名函数,也就是上面$setvalue代表的匿名函数。
  28. //该方法第二参数代表要绑定的类的一个实例,换个角度看就是说匿名函数中的this代表哪个实例化的对象,在这段代码中没有单独new一个对象出来,而是在参数里直接new。
  29. //该方法第三个参数代表类作用域,在使用的时候就是用绑定类的类名。因为这里访问了类的私有成员,只有在其所在的类中才能被访问,因此必须指出类的作用域,不然就会报错。
  30. //因为使用了命名空间,而Youth作为Closure的参数,使用非限定名称会报错,应该使用完全限定或者限定名称
  31. $newSetValueFun = Closure::bind($setValueFun,new Youth,'php\demo\part1\Youth');
  32. $newSetValueFun('Lucy','female',21,45);
  33. //经验证最后输出:Lucy的性别是female,今年21岁,体重有45Kg

bindto()绑定方法

  1. namespace php\demo\part1;
  2. use Closure;
  3. //空行
  4. //首先定义一个用来演示的类
  5. class Youth
  6. {
  7. public $name;
  8. static $gender = 'female';
  9. protected $age = 18;
  10. private $weight = 50;
  11. public function show(){
  12. //非静态成员是通过this关键字和->结合来访问,因此public和private属性访问方法相同
  13. return $this->name.'的性别是'.self::$gender.',今年'.$this->age.'岁,体重有'.$this->weight.'Kg';
  14. }
  15. }
  16. class user extends Youth{
  17. //....
  18. }
  19. //定义一个匿名函数,这个函数先尝试修改类中静态成员gender的值,并将实例化对象中各成员的值输出
  20. $setValueFun = function (){
  21. self::$gender = 'male';
  22. //因为这个函数将要和类绑定,绑定后就像类中已经定义的一个方法一样,因此在代码中要用$this->name来访问类中的属性
  23. return $this->name.'的性别是'.self::$gender.',今年'.$this->age.'岁,体重有'.$this->weight.'Kg';
  24. };
  25. //将Youth类实例出一个对象,并给各赋值
  26. $obj = new user();
  27. $obj->name = 'Lily';
  28. //再实例化一个对象,用来对比
  29. $obj1 = new user();
  30. $obj1->name = 'Lucy';
  31. //bindto()是Closure类中的一个方法,其返回值是个匿名函数。
  32. //该方法第一参数代表要绑定的类的一个实例,换个角度看就是说匿名函数中的this代表哪个实例化的对象,也就是this取值是多少。
  33. //该方法第二个参数代表类作用域,在使用的时候就是用绑定类的类名。
  34. //示例一:演示调用父类和子类的区别,会发现在调用子类时private属性因为不能继承,而无法显示
  35. $newSetValueFun =$setValueFun->bindto($obj,'php\demo\part1\Youth');
  36. echo $newSetValueFun();
  37. echo '<br>';
  38. //输出Lily的性别是male,今年18岁,体重有50Kg
  39. $newSetValueFun =$setValueFun->bindto($obj,'php\demo\part1\user');
  40. echo $newSetValueFun();
  41. echo '<br>';
  42. //输出Lily的性别是male,今年18岁,体重有Kg,发现这里的体重没有了
  43. //示例二:演示调用不同对象时,得到的结果不一样
  44. $newSetValueFun =$setValueFun->bindto($obj,'php\demo\part1\Youth');
  45. echo $newSetValueFun();
  46. echo '<br>';
  47. //输出Lily的性别是male,今年18岁,体重有50Kg
  48. $newSetValueFun =$setValueFun->bindto($obj1,'php\demo\part1\Youth');
  49. echo $newSetValueFun();
  50. echo '<br>';
  51. //输出Lucy的性别是male,今年18岁,体重有50Kg
  52. //你会发现虽然$obj和$obj1都是子类user实例化出来的对象,但是因为bingto()中最后一个参数都是Youth类,所以private属性weight的值还是能显示出来
  53. //同时,因为$obj和$obj1中对name属性赋值不一样,也导致最后输出的结果不一样。
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post