PHP的继承方法如何获取子类名?get_class() 和 get_called_class()

   

PHP里的__CLASS__这类东西是静态绑定的,如果不在子类里重载的话,那么继承父类方法所得到的依旧是父类的名称,而不是子类的名称,比如:

01 <?php
02 class A
03 {
04     function __construct()
05     {
06         echo __CLASS__;
07     }
08  
09     static function name()
10     {
11         echo __CLASS__;
12     }
13 }
14  
15 class extends A
16 {
17 }
18  
19 $objB new B(); // 输出 A
20 B::name();       // 输出 A

此时,无论将B实例化还是直接调用静态方法,echo出来的都会是A。

 

而实际上我想要得到的是子类B的名称!那如何实现呢?

PHP自带两个函数 get_class() 和 get_called_class() 可以解决这个问题。

get_class()用于实例调用,加入参数($this)可解决子类继承调用的问题,而get_called_class()则是用于静态方法调用。

注意,注意, 注意:虽说get_called_class()是用于静态方法调用,但它也可用于类的非静态方法中,但必须强调一点,get_called_class()所处的函数必须在类里面;

需要注意的是get_called_class()需要 PHP>=5.3.0 才支持,官方手册:http://php.net/manual/en/function.get-called-class.php,对于 PHP5.3.0以下的版本,有人给出了如下实现方式:

01 <?php
02 if (!function_exists('get_called_class'))
03 {
04     class classTools
05     {
06         private static $i = 0;
07         private static $file = null;
08  
09         public static function get_called_class()
10         {
11             $bt = debug_backtrace();
12  
13             // 使用 call_user_func 或 call_user_func_array 函数调用类方法,处理如下
14             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'))
15             )
16             {
17                 // 如果参数是数组
18                 if (is_array($bt[3]['args'][0]))
19                 {
20                     $toret $bt[3]['args'][0][0];
21  
22                     return $toret;
23                 }
24                 else if (is_string($bt[3]['args'][0]))
25                 {
26                     // 如果参数是字符串
27                     // 如果是字符串且字符串中包含::符号,则认为是正确的参数类型,计算并返回类名
28                     if (false !== strpos($bt[3]['args'][0], '::'))
29                     {
30                         $toret explode('::'$bt[3]['args'][0]);
31  
32                         return $toret[0];
33                     }
34                 }
35             }
36  
37             // 使用正常途径调用类方法,如:A::make()
38             if (self::$file == $bt[2]['file'] . $bt[2]['line'])
39             {
40                 self::$i++;
41             }
42             else
43             {
44                 self::$i = 0;
45                 self::$file $bt[2]['file'] . $bt[2]['line'];
46             }
47             $lines = file($bt[2]['file']);
48             preg_match_all('/([a-zA-Z0-9\_]+)::' $bt[2]['function'] . '/'$lines[$bt[2]['line'] - 1], $matches);
49  
50             return $matches[1][self::$i];
51         }
52     }
53  
54     function get_called_class()
55     {
56         return classTools::get_called_class();
57     }
58 }

现在,把例子修改下:

01 <?php
02 class A
03 {
04     function __construct()
05     {
06         echo get_class($this);
07     }
08  
09     static function name()
10     {
11         echo get_called_class();
12     }
13 }
14  
15 class extends A
16 {
17 }
18  
19 $objB new B(); // 输出 B
20 B::name();       // 输出 B

呵呵,这是我想要的结果!
转载出处:http://blog.snsgou.com/post-874.html?utm_source=tuicool

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值