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
呵呵,是我想要的结果!
Example #1 get_called_class() 的使用
<?php
class foo
{
public static function test()
{
var_dump(get_called_class());
}
}
class bar extends foo
{
}
foo::test();
bar::test();
以上例程会输出:
string(3) “foo”
string(3) “bar”
<?php
class someClass
{
public static $container = '2';
public function someMethod()
{
echo static::$container === self::$container;
}
}
$anObject = new someClass();
$anObject->someMethod(); //输出1,也就是true啦。
搜索
标签
study
ab
amap
apache
apahe
awk
aws
bat
centos
CFS
chrome
cmd
cnpm
composer
consul
crontab
css
curl
cygwin
devops
di
docker
docker,docker-compose
ethereum
excel
fiddler
fluentd
framework
front-end
git
gitgui
github
glide
go
golang
gorm
grafana
gzip
ioc
item2
iterm2
javascript
jenkins
jsonp
kafka
laradock
laravel
larval
linux
liunux
log
mac
mac, wi-fi
macos
magento
mariaDB
minikube
mongoDB
msp
mysql
netbeans
nginx
nodejs
nohup
npm
nsq
oracle
php
php-fpm
php7
phpstorm
php扩展
Protobuf
python
redis
scp
server
shell
soap
socket
socket5
sql
sre
ssdb
ssh
ssl
study
sublime
swift
system
td-agent
uml
v2ray
vagrant
vagrnat
vim
vpn
vue
vue.js
webpack
webrtc
websocket
webtatic
windows
windows7
word
wps
xdebug
yarn
yii2
yum
zookeeper
世界国家
互联网
以太坊
分类
前端
小程序
打印机
排序算法
搞笑
权限
粤语
缓存
网络
虚拟机
视频
设计模式
项目管理
热门文章
友情链接