zoukankan      html  css  js  c++  java
  • 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延迟静态绑定

  • 相关阅读:
    Zabbix的SNMPTrap监控配置
    Delphi 7下最小化到系统托盘
    解决来QQ消息后歌曲音量降低问题
    转载——用Mixer API函数调节控制面板的音频设置
    git branch -D 大写的D 删除分支
    gitlab+TortoiseGit中使用SSH
    SQL 高级查询
    正则表达式校验文件路径
    显示所选择文件的路径地址
    Type InvokeMember()用法简介
  • 原文地址:https://www.cnblogs.com/52php/p/5677694.html
Copyright © 2011-2022 走看看