PHP的继承方法如何获取子类名?get_class() 和 get_called_class()
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() 和 get_called_class()的更多相关文章
- PHP的继承方法如何获取子类名
http://blog.csdn.net/zls986992484/article/details/53154097 PHP后期静态绑定问题:例如 <?php class A { functio ...
- JS获取节点的兄弟,父级,子级元素的方法(js获取子级获取到换行与空格元素-FF)
先说一下JS的获取方法,其要比JQUERY的方法麻烦很多,后面以JQUERY的方法作对比. JS的方法会比JQUERY麻烦很多,主要则是因为FF浏览器,FF浏览器会把你的换行也当最DOM元素 < ...
- layer父界面调用子弹窗的方法和获取子弹窗的元素值总结
layer.open({ type: 2 ,title: false //不显示标题栏 ,closeBtn: false ,area: ['460px', '45%'] ,shade: 0.5 ,id ...
- JavaScript从父页面获取子页面的值(子页面又如何访问父页面)
之前还真没做过类似的东西,,top页面获取子页面的document.. 在百度搜了下即找到这个东东,还好,能用. 主要就是使用 contentWindow方法,获取子页面的所有document,再做处 ...
- iOS NSString类中获取子字符串
NSString类中提供了这样三个方法用于获取子字符串: – substringFromIndex://取字符串长度从0开始,当index=str.length时字符串为空"" – ...
- JSDOM获取子节点的一些方法
一般情况获取子节点,通过找到查找父节点的ID或者class类名,来获取父节点,再通过children属性,得到子节点的数组: 之前在另外一篇随笔中说过,如果使用另一个属性childNode,会把注释. ...
- 统计文件种类数+获取子shell返回值的其它方法
前言 只是作为一个shell的小小练习和日常统计用,瞎折腾的过程中也是摸到了获取子shell返回值的几种方法: 肯定还有别的方法,跟进程间的通信相关,希望你能提出建议和补充,谢谢~ 完整程序: #! ...
- layer.open参数;layer.open关闭事件;layer.open关闭刷新;layer.open获取子页的值;layer.open调用子页面的方法
父页面 function layerOpen() { layer.open({ type: 2, shade: [0], title: "验收申请", area: ['1024px ...
- vue 父组件主动获取子组件的数据和方法 子组件主动获取父组件的数据和方法
Header.vue <template> <div> <h2>我是头部组件</h2> <button @click="getParen ...
随机推荐
- 从一个url输入浏览器到页面渲染出来,这个过程都发生了哪些事情?
经典问题:在浏览器输入一个url后,会发生什么事情呢? (1)假设是简单的http请求(GET),IPV4,无代理. 浏览器先查看浏览器缓存-系统缓存-路由器缓存,若缓存中有,请略过中间步骤,直接跳到 ...
- h3c防火墙的设置过程
公司采购了一款h3c的防火墙,型号为F100-E-G,以前也设置过H3C的防火墙,不过这次还是设置还是有各种问题,所以把设置过程记录下来,方便以后查阅. 一.防火墙一般在0口都设置一个默认的IP地址1 ...
- [转载]python:open/文件操作
open/文件操作f=open('/tmp/hello','w') #open(路径+文件名,读写模式) #读写模式:r只读,r+读写,w新建(会覆盖原有文件),a追加,b二进制文件.常用模式 如:' ...
- sicily 猴子选大王
题目描述 猴子选大王,有N只猴子,从1-N进行编号.它们按照编号的顺时针方向,排成一个圆圈,然后从第一只猴子开始报数.第一只猴子报1,以后每只猴子报的数字都是它前面猴子所报数字加1.如果一只猴子报的数 ...
- 线程私有数据和pthread_once
#include <stdio.h> #include <pthread.h> pthread_key_t key; pthread_once_t ponce = PTHREA ...
- jQuery load()方法用法集锦!
调用load方法的完整格式是:DE>load( url, [data], [callback] ),其中DE> DE>urlDE>:是指要导入文件的地址. DE>data ...
- Android 高清加载巨图方案 拒绝压缩图片
Android 高清加载巨图方案 拒绝压缩图片 转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/49300989: 本文出自:[张 ...
- p2p网贷平台设计简析
以我之前主持开发的一个商业产品:p2p网贷为例进行分析.整个的概况,可以参见:www.huixinp2p.com(目的只会技术交流) 界面可以直接参考前期博客:http://www.cnblogs.c ...
- C/C++实践笔记 005
整型常量int a=101u; 无符号整数int b=102l; 长整数int c=103ll; long long整数 存储qq号,手机号 010八进制 0x10十六进制 嵌入式的场合经常用shor ...
- JS组件系列——分享自己封装的Bootstrap树形组件:jqTree
前言:之前的一篇介绍了下如何封装自己的组件,这篇再次来体验下自己封装组件的乐趣.看过博主博客的园友应该记得之前分享过一篇树形菜单的使用JS组件系列——Bootstrap 树控件使用经验分享,这篇里面第 ...