PHP的继承方法如何获取子类名?get_class() 和 get_called_class()
PHP里的__CLASS__这类东西是静态绑定的,如果不在子类里重载的话,那么继承父类方法所得到的依旧是父类的名称,而不是子类的名称,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php class A { function __construct() { echo __CLASS__ ; } static function name() { echo __CLASS__ ; } } class B extends A { } $objB = new B(); // 输出 A B::name(); // 输出 A |
此时,无论将B实例化还是直接调用静态方法,echo出来的都会是A。
而实际上我想要得到的是子类B的名称!那如何实现呢?
PHP自带两个函数 get_class() 和 get_called_class() 可以解决这个问题。
get_class()用于实例调用,加入参数($this)可解决子类继承调用的问题,而get_called_class()则是用于静态方法调用。
需要注意的是:get_called_class()需要 PHP>=5.3.0 才支持,官方手册:http://php.net/manual/en/function.get-called-class.php,对于 PHP5.3.0以下的版本,有人给出了如下实现方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <?php if (!function_exists( 'get_called_class' )) { class classTools { private static $i = 0; private static $file = null; public static function get_called_class() { $bt = debug_backtrace(); // 使用 call_user_func 或 call_user_func_array 函数调用类方法,处理如下 if ( array_key_exists (3, $bt ) && array_key_exists ( 'function' , $bt [3]) && in_array( $bt [3][ 'function' ], array ( 'call_user_func' , 'call_user_func_array' )) ) { // 如果参数是数组 if ( is_array ( $bt [3][ 'args' ][0])) { $toret = $bt [3][ 'args' ][0][0]; return $toret ; } else if ( is_string ( $bt [3][ 'args' ][0])) { // 如果参数是字符串 // 如果是字符串且字符串中包含::符号,则认为是正确的参数类型,计算并返回类名 if (false !== strpos ( $bt [3][ 'args' ][0], '::' )) { $toret = explode ( '::' , $bt [3][ 'args' ][0]); return $toret [0]; } } } // 使用正常途径调用类方法,如:A::make() if (self:: $file == $bt [2][ 'file' ] . $bt [2][ 'line' ]) { self:: $i ++; } else { self:: $i = 0; self:: $file = $bt [2][ 'file' ] . $bt [2][ 'line' ]; } $lines = file( $bt [2][ 'file' ]); preg_match_all( '/([a-zA-Z0-9\_]+)::' . $bt [2][ 'function' ] . '/' , $lines [ $bt [2][ 'line' ] - 1], $matches ); return $matches [1][self:: $i ]; } } function get_called_class() { return classTools::get_called_class(); } } |
现在,把例子修改下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php class A { function __construct() { echo get_class( $this ); } static function name() { echo get_called_class(); } } class B extends A { } $objB = new B(); // 输出 B B::name(); // 输出 B |
呵呵,这是我想要的结果!
延伸阅读:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· 程序员常用高效实用工具推荐,办公效率提升利器!
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 【译】WinForms:分析一下(我用 Visual Basic 写的)