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 返回对象的类名

PHP get_class_methods函数用法

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

时间: 2024-10-12 08:00:39

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

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

http://blog.csdn.net/zls986992484/article/details/53154097 PHP后期静态绑定问题:例如 [php] <?php class A { function __construct() { echo __CLASS__; } static function name() { echo __CLASS__; } } class B extends A { } $objB = new B(); // 输出 A B::name();       //

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

1 layer.open({ 2 type: 2 3 ,title: false //不显示标题栏 4 ,closeBtn: false 5 ,area: ['460px', '45%'] 6 ,shade: 0.5 7 ,id: 'LAY_layuipro·' //设定一个id,防止重复弹出 8 ,btn: ['确定','取消'] 9 ,btn1: function(index, layero){ 10 11 var body = layer.getChildFrame('body', ind

NSString类中三个用于获取子字符串的方法:

NSString类中提供了这样三个方法用于获取子字符串: – substringFromIndex: – substringWithRange: – substringToIndex: 它们该怎么使用呢?见下面代码即可知道. NSString *str = @"12345"; -substringFromIndex: 以指定索引开始(包括指定索引的字符,索引从0开始),并包括之后的全部字符: // NSString *subString0 = [str substringFromInd

JQuery获取子孩子和兄弟元素的方法

这里说的获取当前元素的子孩子和兄弟元素的方法,另外还有遍历和指定的具体要求: 01.html代码: <!DOCTYPE html> <html> <head> <title>测试jquery</title> <meta charset="utf-8"/> <link rel="stylesheet" type="text/css" href="01.css&q

js 下获取子元素的方法

笔记核心: firstElementChild只会获取元素节点对象,从名称就可以看出来,firstChild则可以获取文本节点对象(当然也可以获取元素节点对象),比如空格和换行都被当做文本节点. js不同于jQuery,在获取DOM时,有很多不方便的地方,哎,没办法,原始的东东,虽然万能,但却不方便. 咱今天在使用原生js的时候,就遇见一个坑------>firstChild,具体是使用firstChild获取元素的第一个子节点,可是相当的悲剧!!! 这个是一个小模型: <div> &l

subString,split方法——获取子字符串,分割數組

1.2.31 subString方法——获取子字符串本文所属图书 > Java程序开发参考手册 subString方法实现对字符串从指定的索引位置开始截取,直到此字符串的末尾,并返回一个新的字符串. 语法1 public String subString(int beginIndex) 返回值:指定的子字符串. 参数:beginIndex为开始处的索引(包括该位置). 示例 本示例使用subString方法截取字符串strCom,索引位置从3开始截取到字符串strCom的结尾处,并将截取的结果赋

JS获取子节点、父节点和兄弟节点的方法实例总结

JS获取子节点.父节点和兄弟节点的方法实例总结 原生js 参考网址 Jquery 参考网址 原文地址:https://www.cnblogs.com/renxiuxing/p/10180558.html

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

父组件主动获取子组件的数据和方法 1.父组件Home.vue <template> <div> <h2>{{msg}}</h2> <!-- 1.调用子组件的时候调用一个ref --> <!-- 2.在父组件中通过this.$refs.header.数据 this.$refs.header.方法 调用子组件的数据和方法 --> <!-- 注意,第一步是ref,第二步是refs --> <v-header ref=&qu

c# 获取方法所在的命名空间 类名 方法名

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.Reflection; namespace GetMethodNameSpace { class Program { public static string GetMethodInfo() { string str = ""; //取得当