PHP获取类私有属性的3种方法


Posted in PHP onSeptember 10, 2020

今天在推上看到一条获取PHP类私有属性的推文,感觉很有意思:

PHP获取类私有属性的3种方法

顺着推文联想,还有其他方式吗?经过自己的测试及网上答案,总结出三种方法:

1. 反射

反射可以获取类的详细信息,要获取私有属性的值,只需将对应属性的ReflectionProperty实例设置为可访问再取值即可。示例代码如下:

namespace tlanyan;

class Foo {
 private $bar = "Foo bar!";
}

// 获取反射类及反射属性
$class = new \ReflectionClass(Foo::class);
$property = $class->getProperty("bar");
// 设置属性可访问
$property->setAccessible(true);

$foo = new Foo;
// 获取对象属性值
// 注意:只能通过 ReflectionProperty 实例的 getValue 方法访问
// 不能这样直接访问: $foo->bar;
echo $property->getValue($foo), PHP_EOL:
// 输出: Foo bar!

本人之前写过“PHP回顾之反射”一文,比较详细的介绍了反射及用法,有兴趣的阅读参考。

2. 转换成数组

这种方法用将对象强制转换成数组,再通过键获取其值。示例代码如下:

class Foo {
 private $bar = "Foo bar!";
}

$foo = new Foo;
// 强制转型
$attrs = (array)$foo;
// 拼接key,注意 "\0" 不能改成单引号!
$key = "\0" . Foo::class . "\0" . "bar";
echo $attrs[$key], PHP_EOL;
// 输出: Foo bar!

上述代码中key的拼接方式比较诡异,key规则如下:

  1. public属性, key是 属性名;
  2. protected属性,key是 \0*\0属性名;
  3. private属性, key是 \0类名\0属性名。

注意 \0 是一个字符(不是两个),对应的ASCII码是数字0。编程时要用双引号将其引起来。不能使用单引号,否则转义失效,那就是两个字符。如果你有C语言基础,应该知道 \0 就是字符串的结束符。这个符号直接输出不会显示,但可以通过strlen或者ord让其现形:

foreach ($attrs as $key => $value) {
 echo "key:$key", ", key length:", strlen($key), ", ascii: ";
 for ($i = 0; $i < strlen($key); ++ $i) {
 echo ord($key[$i]), " "; 
 }
 echo PHP_EOL;
}
// 输出
// key:Foobar, key length:8, ascii: 0 70 111 111 0 98 97 114
// Foobar 有6个字符,加上两个不显示字符,所以长度是8

还需要注意拼接private属性时类名应该是 “完全限定类名” ,建议通过Foo::class的方式获取。

与强制转换成数组类似的另一种方法是serialize,但是serialize比较慢,并且序列化后的字符串更难辨认结构和处理,不建议使用。

3. 闭包

文章开头的推特截图已经展示了闭包的用法,其中call方法在PHP7中引入,另一个是PHP5.4引入的bindTocallbindTo的用法示例如下:

namespace tlanyan;

class Foo {
 private $bar = "Foo bar!";
}

$foo = new Foo;
// 闭包(匿名函数)是PHP5.3引入的功能
$closure = function() { return $this->bar; };
// PHP5.4起支持bindTo方法
$method = $closure->bindTo($foo, Foo::class);
echo $method(), PHP_EOL;

// PHP7引入call方法,可绑定this直接执行
echo $closure->call($foo), PHP_EOL;

bindTo方法的第二个参数注意传入对象的 “完全限定类名”,指示函数应该放置在该类的作用域下,从而可以访问私有属性。

总结

性能: 数组 > 反射 > 闭包

易用性: 闭包 > 数组 > 反射

推荐: 闭包 > 反射 > 数组

以上就是PHP获取类私有属性的3种方法的详细内容,更多关于PHP获取类私有属性的资料请关注三水点靠木其它相关文章!

PHP 相关文章推荐
杏林同学录(五)
Oct 09 PHP
用PHP实现弹出消息提示框的两种方法
Dec 17 PHP
thinkphp学习笔记之多表查询
Jul 28 PHP
PHP下的Oracle客户端扩展(OCI8)安装教程
Sep 10 PHP
php生成QRcode实例
Sep 22 PHP
php实现格式化多行文本为Js可用格式
Apr 15 PHP
PHP/HTML混写的四种方式总结
Feb 27 PHP
Yii 访问 Gii(脚手架)时出现 403 错误
Jun 06 PHP
Laravel框架在本地虚拟机快速安装的方法详解
Jun 11 PHP
thinkPHP5.0框架事务处理操作简单示例
Sep 07 PHP
PHP创建文件及写入数据(覆盖写入,追加写入)的方法详解
Feb 15 PHP
PHP实现文件上传后台处理脚本
Mar 04 PHP
php实现图片压缩处理
Sep 09 #PHP
如何在PHP中读写文件
Sep 07 #PHP
PHP延迟静态绑定使用方法实例解析
Sep 05 #PHP
PHP autoload使用方法及步骤详解
Sep 05 #PHP
PHP数组访问常用方法解析
Sep 05 #PHP
XAMPP升级PHP版本实现步骤解析
Sep 04 #PHP
php使用Swoole实现毫秒级定时任务的方法
Sep 04 #PHP
You might like
php array_map()数组函数使用说明
2011/07/12 PHP
PHP面向对象学习笔记之一 基础概念
2012/10/06 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
Js+XML 操作
2006/09/20 Javascript
javascript的键盘控制事件说明
2008/04/15 Javascript
javascript Discuz代码中的msn聊天小功能
2008/05/25 Javascript
jquery获取ASP.NET服务器端控件dropdownlist和radiobuttonlist生成客户端HTML标签后的value和text值
2010/06/28 Javascript
扩展JavaScript功能的正确方法(译文)
2012/04/12 Javascript
jquery 关于event.target使用的几点说明介绍
2013/04/26 Javascript
Knockout数组(observable)使用详解示例
2013/11/15 Javascript
js的hasownproperty使用示例
2014/03/02 Javascript
Javascript 赋值机制详解
2014/11/23 Javascript
JavaScript中String.match()方法的使用详解
2015/06/06 Javascript
js仿黑客帝国字母掉落效果代码分享
2020/11/08 Javascript
js实现将json数组显示前台table中
2017/01/10 Javascript
angular实现form验证实例代码
2017/01/17 Javascript
微信小程序如何刷新当前界面的实现方法
2019/06/07 Javascript
微信小程序动态添加和删除组件的现实
2020/02/28 Javascript
python的类变量和成员变量用法实例教程
2014/08/25 Python
Python计算回文数的方法
2015/03/11 Python
用Python制作简单的朴素基数估计器的教程
2015/04/01 Python
详解Python验证码识别
2016/01/25 Python
windows10系统中安装python3.x+scrapy教程
2016/11/08 Python
python安装numpy&amp;安装matplotlib&amp; scipy的教程
2017/11/02 Python
解决Matplotlib图表不能在Pycharm中显示的问题
2018/05/24 Python
基于OpenCV python3实现证件照换背景的方法
2019/03/22 Python
Python pymsql模块的使用
2020/09/07 Python
面向对象编程OOP的优点
2013/01/22 面试题
工作时间上网检讨书
2014/02/03 职场文书
解除劳动合同协议书范本
2014/04/14 职场文书
推荐信格式范文
2014/05/09 职场文书
会计演讲稿范文
2014/05/23 职场文书
百日安全生产活动总结
2014/07/05 职场文书
旅游与酒店管理专业求职信
2014/07/21 职场文书
教师业务学习材料
2014/12/16 职场文书
浅谈MySQL之select优化方案
2021/08/07 MySQL