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

<?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以下的版本,有人给出了如下实现方式:

<?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();
}
}

现在,把例子修改下:

<?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

呵呵,这是我想要的结果!

延伸阅读:

PHP get_class 返回对象的类名

PHP get_class_methods函数用法

父类方法返回子类实例:PHP延迟静态绑定

PHP的继承方法如何获取子类名?get_class() 和 get_called_class()的更多相关文章

  1. PHP的继承方法如何获取子类名

    http://blog.csdn.net/zls986992484/article/details/53154097 PHP后期静态绑定问题:例如 <?php class A { functio ...

  2. JS获取节点的兄弟,父级,子级元素的方法(js获取子级获取到换行与空格元素-FF)

    先说一下JS的获取方法,其要比JQUERY的方法麻烦很多,后面以JQUERY的方法作对比. JS的方法会比JQUERY麻烦很多,主要则是因为FF浏览器,FF浏览器会把你的换行也当最DOM元素 < ...

  3. layer父界面调用子弹窗的方法和获取子弹窗的元素值总结

    layer.open({ type: 2 ,title: false //不显示标题栏 ,closeBtn: false ,area: ['460px', '45%'] ,shade: 0.5 ,id ...

  4. JavaScript从父页面获取子页面的值(子页面又如何访问父页面)

    之前还真没做过类似的东西,,top页面获取子页面的document.. 在百度搜了下即找到这个东东,还好,能用. 主要就是使用 contentWindow方法,获取子页面的所有document,再做处 ...

  5. iOS NSString类中获取子字符串

    NSString类中提供了这样三个方法用于获取子字符串: – substringFromIndex://取字符串长度从0开始,当index=str.length时字符串为空"" – ...

  6. JSDOM获取子节点的一些方法

    一般情况获取子节点,通过找到查找父节点的ID或者class类名,来获取父节点,再通过children属性,得到子节点的数组: 之前在另外一篇随笔中说过,如果使用另一个属性childNode,会把注释. ...

  7. 统计文件种类数+获取子shell返回值的其它方法

    前言 只是作为一个shell的小小练习和日常统计用,瞎折腾的过程中也是摸到了获取子shell返回值的几种方法: 肯定还有别的方法,跟进程间的通信相关,希望你能提出建议和补充,谢谢~ 完整程序: #! ...

  8. layer.open参数;layer.open关闭事件;layer.open关闭刷新;layer.open获取子页的值;layer.open调用子页面的方法

    父页面 function layerOpen() { layer.open({ type: 2, shade: [0], title: "验收申请", area: ['1024px ...

  9. vue 父组件主动获取子组件的数据和方法 子组件主动获取父组件的数据和方法

    Header.vue <template> <div> <h2>我是头部组件</h2> <button @click="getParen ...

随机推荐

  1. TCP/IP四层模型和OSI七层模型

    TCP/IP四层模型 TCP/IP是一组协议的代名词,它还包括许多协议,组成了TCP/IP协议簇.TCP/IP协议簇分为四层,IP位于协议簇的第二层(对应OSI的第三层),TCP位于协议簇的第三层(对 ...

  2. Hibernate 分组查询 子查询 原生SQL

    分组查询: 使用group by关键字对数据分组,使用having关键字对分组数据设定约束条件,从而完成对数据分组和统计 1.1 聚合函数:常被用来实现数据统计功能 ① count() 统计记录条数 ...

  3. java数组初始化函数

    用法1:接受2个参数Arrays.fill( a1, value );注:a1是一个数组变量,value是一个a1中元素数据类型的值,作用:填充a1数组中的每个元素都是value例如:boolean[ ...

  4. python高级之生成器&迭代器

    python高级之生成器&迭代器 本机内容 概念梳理 容器 可迭代对象 迭代器 for循环内部实现 生成器 1.概念梳理 容器(container):多个元素组织在一起的数据结构 可迭代对象( ...

  5. Sublime Text 3 3126 注册码 + 下载地址

    Sublime Text 3 3126  下载地址 Windows版本 64位:https://download.sublimetext.com/Sublime%20Text%20Build%2031 ...

  6. GHOST急速安装win10或win7

    首先说说写这篇博客的原因,我自己曾经被装各种系统弄得焦头烂额,各种刻光盘光驱安装,写优盘安装以及pe盘恢复系统等等,每次都各种方式尝试一下,太浪费时间了,所以天真的想着能不能有一个类似"一劳 ...

  7. 安装MySQL的时候遇到的错误

    这里我安装的是MySQL5.6 我遇到的错误有 (1)Warning: Bison executable not found in PATH 解决办法: yum install bison 原文摘自: ...

  8. 七牛图片上传JSSDK

    BASE64图片上传 接口说明: POST /putb64/<Fsize>/key/<EncodedKey>/mimeType/<EncodedMimeType>/ ...

  9. 深夜重温JavaScript中的对象和数组

    这一块实际上已经学过了,因为没有学好,在工作过程中遇到一些对象或者数组的操作,会去百度查找,浪费了许多宝贵的时间,所以特地再拐过头来重新学习. 对象 基本概念: 对象这种基本的数据结构还有其他很多种叫 ...

  10. ARM处理器解析

    按图分析: ARM处理器有七种工作模式,为的是形成不同的使用级别,以防造成对系统的破坏.不同模式可以访问的寄存器不同,可以运行的指令不同. (1)user(10000):普通应用程序运行的模式(应用程 ...