Blogger Information
Blog 30
fans 0
comment 1
visits 22016
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
0214 PHP闭包与异常
Admin
Original
1015 people have browsed it

0214 PHP闭包与异常

PHP闭包

你可以把闭包当作是匿名函数
闭包的最常用的场景: 就是做为函数/方法的回调参数
也可以将父级中的变量/状态封装进匿名函数

  1. namespace chapter5;
  2. //闭包常用于,作为函数或者方法的回调参数
  3. //示例
  4. $data = ['id'=>1,'name'=>'xiaoyu','pwd'=>'xiaoyu'];
  5. $cc = array_filter($data,function ($key){
  6. return in_array($key,['id','name']);
  7. },ARRAY_FILTER_USE_KEY);
  8. var_dump($cc);
  9. //势力在此处闭包的作用为作为array_filter的回调参数

接下来如何利用闭包与对象或类绑定来访问类成员
在此之前先说一下几个魔术方法

  • __invoke 当类被当成函数使用时所执行
  • __toSring 当类被当成字符串时
  • __callStatic 执行一个不存在的静态方法时
    Closure类
  • 实例方法: bindTo()复制当前闭包对象,绑定指定$this和类作用域
  • 静态方法: bind(): 复制一个闭包, 绑定指定$this和类作用域
    1. namespace chapter5;
    2. $closure = function (string $data, string $method) : string{
    3. return $data . ':' .$method;
    4. };
    5. echo get_class($closure);
    6. echo '<hr>';
    7. class demo
    8. {
    9. //当对象被当成函数使用时
    10. public function __invoke()
    11. {
    12. return '你把我当成函数用了!';
    13. }
    14. //当对象被当成字符串直接使用时
    15. public function __toString()
    16. {
    17. return '你把我当成字符串了';
    18. }
    19. }
    20. $test = new demo;
    21. echo $test;
    22. echo '<br>';
    23. echo $test();

    为了方便起见我们会用到toString比较多
    1. namespace chapter5;
    2. use Closure;
    3. class info
    4. {
    5. public $name = '我';
    6. public $school = '家';
    7. public function __toString()
    8. {
    9. return $this->name . '在' . $this->school;
    10. }
    11. }
    12. $test = new info;
    13. echo $test;
    14. //创建一个闭包用闭包来提
    15. $bb = function (string $name, string $school) : void{
    16. $this->name = $name;
    17. $this->school = $school;
    18. };
    19. $clouser=$bb->bindTo($test);
    20. $clouser('周小雨','学校');
    21. echo $test;
    22. echo '<hr>';
    23. $bb = function (string $name, string $school) : void{
    24. $this->name = $name;
    25. $this->school = $school;
    26. };
    27. $clouser = Closure::bind($bb,$test);
    28. $clouser('我','上课');
    29. echo $test;
    30. class imp
    31. {
    32. public static $xiaoyu = 'ok';
    33. public static $home = 'zj';
    34. //当访问一个类中不存在的静态方法时自动触发
    35. public static function __callStatic($name, $arguments)
    36. {
    37. return static::$xiaoyu . '在' . static::$home;
    38. }
    39. }
    40. echo imp::xiaoyu();
    41. $bb = function (string $name, string $school) : void{
    42. static::$xiaoyu = $name;
    43. static::$home = $school;
    44. };
    45. echo '<hr>';
    46. $clouser = $bb->bindTo(null,imp::class);
    47. $clouser('我','上课');
    48. echo imp::xiaoyu();
    49. echo '<hr>';
    50. $clouser = Closure::bind($bb,null,imp::class);
    51. $clouser('bind','安排');
    52. echo imp::xiaoyu();

    接下来是异常

    异常这边还是要说几句的,try里面是放执行的代码,而throw是来使用异常的,就是说假设你的代码没有问题throw是不会被执行捕捉异常的,假设你代码出现问题报错,啥的就会执行。catch(你在throw里面new的异常类名 空格一下 对象(随便起个名)catch里面输出对象即可)
    1. namespace chapter5;
    2. use Exception;
    3. //设置一个用户
    4. $users = [
    5. ['id'=>1,'username'=>'test','password'=>'test'],
    6. ];
    7. $username = 'test1';
    8. $password = 'test';
    9. $d = array_filter($users,function ($users) use ($username,$password){
    10. return $users['username'] === $username && $users['password'] === $password;
    11. });
    12. try{
    13. if(count($d) != 1){
    14. echo '登陆成功';
    15. throw new Exception('账号或者密码错误','001');
    16. }
    17. } catch (Exception $e){
    18. echo $e->getMessage().'<br>'.$e->getFile();
    19. }
    自己写一个异常类(整好看点)
    1. namespace chapter5;
    2. use Exception;
    3. $users = [
    4. ['id' => 1, 'username' => 'test', 'password' => 'test'],
    5. ];
    6. $username = 'test1';
    7. $password = 'test';
    8. $d = array_filter($users, function ($users) use ($username, $password) {
    9. return $users['username'] === $username && $users['password'] === $password;
    10. });
    11. class myExecption extends Exception
    12. {
    13. public function __toString(): string
    14. {
    15. return <<< Error
    16. <table border="1" cellspacing="0" cellpadding="5">
    17. <tr bgcolor="wheat">
    18. <th>错误信息</th>
    19. <th>代码</th>
    20. <th>文件</th>
    21. <th>行号</th>
    22. </tr>
    23. <tr>
    24. <td>$this->message</td>
    25. <td>$this->code </td>
    26. <td>$this->file </td>
    27. <td>$this->line</td>
    28. </tr>
    29. <tr>
    30. <td colspan = '4'>请更正报错点</td>
    31. </tr>
    32. </table>
    33. Error;
    34. }
    35. }
    36. try{
    37. if(count($d) === 1) echo '登陆成功';
    38. throw new myExecption('账号或密码错误',001);
    39. } catch (myExecption $e){
    40. echo $e;
    41. }

    附加作业

    闭包访问protect/private成员
    其实很简单,因为其都不允许外部调用,所以我们借助公共函数去调用即可!
    我这边申明一个私有成员$xiaoyu再安排了一个公共函数xd(闭包给这个函数传参)用来更改私有成员$xiaoyu的值
    1. namespace chapter5;
    2. class A
    3. {
    4. private $xiaoyu;
    5. protected function test() : string
    6. {
    7. return $this->xiaoyu;
    8. }
    9. public function xd($class) : string
    10. {
    11. return $this->xiaoyu = $class;
    12. }
    13. public function dy()
    14. {
    15. return $this->test();
    16. }
    17. }
    18. $tt = new A;
    19. $bb = function ($name) : void {
    20. $this->xd($name);
    21. };
    22. $bbd = $bb->bindTo($tt);
    23. $bbd('小雨');
    24. echo $tt->dy();
    好了那这就是这次作业,拉下了好多一点点补上去!发现学到的内容都很实用!
Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:代码注释有点少, 考虑一下你博客的访问感受
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