background image

php 的继承方法获取子类名

看了一下 datastore 的入门,以及开始采用 MVC 方式来写 php,于是想拿 php 为 redis
写个 model,可以实现一些 datastore 的基本功能...于是碰到这样一个问题-.-
php 里__CLASS__这类东西是静态绑定的,如果不再子类里重载的话,那么继承父类方
法所得到的依旧是父类的名称而不是子类的名称。比如:
class A{
function __construct(){
echo __CLASS__;
}
static function name(){
echo __CLASS__;
}
}
class B extends A{}
此时无论将 B 实例化还是直接调用静态方法,echo 出来的都会是 A。翻 qeephp 里是用
子类重载的方式解决这个问题,可是这样的话没新搞一个子类就得把相应调用类名的方
法重载一边.....这算是 php 在 oop 上的缺陷吧,试了试 python 上没这个问题。
google 之。找到两个函数 get_class()和 get_called_class()。get_class()用于实例调用,
加入参数($this)可解决子类继承调用的问题,而 get_called_class()则是用于静态方法
调用,可是...这玩意儿只在 php 5.3 以后才有....5.3 还是比较遥远的事...还好 5.2 之前
可 以 手 动 实 现 这 个 函 数 : 参 阅 http://php.net/manual/en/function.get-called-
class.php 下方有高手添加了几种 5.3 之前的实现方式。
if(!function_exists('get_called_class')) {
class class_tools
{
private static $i = 0;
private static $fl = 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];