经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » PHP » 查看文章
后期静态绑定在PHP中的使用
来源:cnblogs  作者:硬核项目经理  时间:2021/3/1 9:28:24  对本文有异议

什么叫后期静态绑定呢?其实我们在之前的文章PHP中的static中已经说过这个东西了。今天我们还是再次深入的理解一下这个概念。

首先,我们通过一段代码来引入后期静态绑定这一概念:

  1. class A
  2. {
  3. public static function who()
  4. {
  5. echo __CLASS__, PHP_EOL;
  6. }
  7. public static function test()
  8. {
  9. self::who();
  10. }
  11. }
  12. class B extends A
  13. {
  14. public static function who()
  15. {
  16. echo __CLASS__, PHP_EOL;
  17. }
  18. }
  19. B::test(); // A

在这段代码中,我们使用了self关键字,当使用B类调用test()静态方法时,self指向的是A类的who()方法,因此,输出的是A。别激动,这是普通的静态绑定。self关键字调用的内容取决于它定义时所在的类。也就是说不管怎么继承,用哪个子类来调用test()方法,self关键字都会调用的是A类的who()方法。

而后期静态绑定呢?其实就有点像实例化的类对象,每个实例化的对象,调用的都是自身,而不是父类的属性方法。普通的静态调用可不是这样,但是现实中我们又有这样的需求,就像实例化对象的调用方式一样来调用静态属性方法,这时,我们就可以使用static关键字来实现后期静态绑定。

  1. class C
  2. {
  3. public static function who()
  4. {
  5. echo __CLASS__, PHP_EOL;
  6. }
  7. public static function test()
  8. {
  9. static::who();
  10. }
  11. }
  12. class D extends C
  13. {
  14. public static function who()
  15. {
  16. echo __CLASS__, PHP_EOL;
  17. }
  18. }
  19. D::test(); // D

当使用static关键字后,这里D类调用的test()方法内部调用的who()就是D类自己了。

官方文档中的定义如下:

当进行静态方法调用时,该类名即为明确指定的那个(通常在 :: 运算符左侧部分);当进行非静态方法调用时,即为该对象所属的类。

该功能从语言内部角度考虑被命名为“后期静态绑定”。“后期绑定”的意思是说,static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。也可以称之为“静态绑定”,因为它可以用于(但不限于)静态方法的调用。

除了self和static关键字外,我们还有一个parent关键字,这个关键字的意义就很明显了,调用父类的静态内容。我们同时用三个关键字一起来进行测试:

  1. class E
  2. {
  3. public static function who()
  4. {
  5. echo __CLASS__, PHP_EOL;
  6. }
  7. public static function test()
  8. {
  9. self::who();
  10. static::who();
  11. }
  12. }
  13. class F extends E
  14. {
  15. public static function who()
  16. {
  17. echo __CLASS__, PHP_EOL;
  18. }
  19. }
  20. class G extends F
  21. {
  22. public static function who()
  23. {
  24. parent::who();
  25. echo __CLASS__, PHP_EOL;
  26. }
  27. }
  28. G::test();
  29. // E
  30. // F
  31. // G

最后,我们再来看两个PHP的方法,一个是get_called_class()方法,用来获取当前调用的是哪个类。在静态方法中可以根据调用方式判断当前类是哪个类来进行其他的业务逻辑操作。另一个是forward_static_call()方法,用于静态方法的调用。

  1. class H
  2. {
  3. public static function who()
  4. {
  5. echo __CLASS__ . ':' . join(',', func_get_args()), PHP_EOL;
  6. }
  7. public static function test()
  8. {
  9. echo get_called_class(), PHP_EOL;
  10. forward_static_call('who', 'a', 'b'); // xxx:a,b
  11. forward_static_call(['I', 'who'], 'c', 'd'); // I:c,d
  12. forward_static_call_array(['H', 'who'], ['e', 'f']); // H:e,f
  13. }
  14. }
  15. class I extends H
  16. {
  17. public static function who()
  18. {
  19. echo __CLASS__ . ':' . join(',', func_get_args()), PHP_EOL;
  20. }
  21. }
  22. function who()
  23. {
  24. echo 'xxx:' . join(',', func_get_args()), PHP_EOL;
  25. }
  26. H::test(); // H
  27. // xxx:a,b
  28. // I:c,d
  29. // H:e,f
  30. I::test(); // I
  31. // xxx:a,b
  32. // I:c,d
  33. // H:e,f

注意,如果forward_static_call()不指定类名的话,将调用全局的方法。forward_static_call_array()则是将参数使用数组进行传递。

测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202001/source/%E5%90%8E%E6%9C%9F%E9%9D%99%E6%80%81%E7%BB%91%E5%AE%9A%E5%9C%A8PHP%E4%B8%AD%E7%9A%84%E4%BD%BF%E7%94%A8.php

参考文档:
https://www.php.net/manual/zh/language.oop5.late-static-bindings.php
https://www.php.net/manual/zh/function.get-called-class.php
https://www.php.net/manual/zh/function.forward-static-call.php

关注公众号:【硬核项目经理】获取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料

知乎、公众号、抖音、头条搜索【硬核项目经理】

B站ID:482780532

原文链接:http://www.cnblogs.com/zyblog-coder/p/14451457.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号