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 相关文章推荐
第六节 访问属性和方法 [6]
Oct 09 PHP
关于PHP中操作MySQL数据库的一些要注意的问题
Oct 09 PHP
PHP网站备份程序代码分享
Jun 10 PHP
jQuery EasyUI API 中文文档 - DateBox日期框
Oct 15 PHP
php多用户读写文件冲突的解决办法
Nov 06 PHP
php模拟登陆的实现方法分析
Jan 09 PHP
PHP获取当前日期和时间及格式化方法参数
May 11 PHP
PHP 中 Orientation 属性判断上传图片是否需要旋转
Oct 16 PHP
PHP书写格式详解(必看)
May 23 PHP
php 访问oracle 存储过程实例详解
Jan 08 PHP
php实现的读取CSV文件函数示例
Feb 07 PHP
PHP序列化的四种实现方法与横向对比
Nov 29 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 Memcached应用实现代码
2010/02/08 PHP
PHP比较运算符的详细介绍
2015/09/29 PHP
详解PHP原生DOM对象操作XML的方法
2016/10/17 PHP
csdn 批量接受好友邀请
2009/02/19 Javascript
javascript来定义类的规范小结
2010/11/19 Javascript
jquery focus(fn),blur(fn)方法实例代码
2011/12/16 Javascript
JavaScript之Getters和Setters 平台支持等详细介绍
2012/12/07 Javascript
完美解决AJAX跨域问题
2013/11/01 Javascript
JS 屏蔽键盘不可用与鼠标右键不可用的方法
2013/11/18 Javascript
JavaScript中的数学运算介绍
2014/12/29 Javascript
项目实践一图片上传之form表单还是base64前端图片压缩(前端图片压缩)
2016/07/28 Javascript
AngularJs bootstrap搭载前台框架——准备工作
2016/09/01 Javascript
浅谈angularjs module返回对象的坑(推荐)
2016/10/21 Javascript
详解Vue.js入门环境搭建
2017/03/17 Javascript
vue-cli脚手架的安装教程图解
2018/09/02 Javascript
Vue模板语法中数据绑定的实例代码
2019/05/17 Javascript
快速解决Vue、element-ui的resetFields()方法重置表单无效的问题
2020/08/12 Javascript
如何使用 vue-cli 创建模板项目
2020/11/19 Vue.js
[56:41]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 Newbee vs OG
2018/04/01 DOTA
[51:17]Mineski vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.22
2019/09/05 DOTA
Python 常用string函数详解
2016/05/30 Python
Python网络爬虫项目:内容提取器的定义
2016/10/25 Python
Opencv-Python图像透视变换cv2.warpPerspective的示例
2019/04/11 Python
Django 开发环境与生产环境的区分详解
2019/07/26 Python
TensorFlow2.X使用图片制作简单的数据集训练模型
2020/04/08 Python
海滩咖啡馆:Beach Cafe
2018/02/02 全球购物
请编程遍历页面上所有 TextBox 控件并给它赋值为 string.Empty
2015/12/03 面试题
个人实用简单的自我评价
2013/10/19 职场文书
汽车专业学生自我评价
2014/01/19 职场文书
高二历史教学反思
2014/01/25 职场文书
数控技术专业毕业自荐书范文
2014/02/05 职场文书
幼儿园小班评语
2014/04/18 职场文书
环保倡议书50字
2014/05/15 职场文书
2014年教师节国旗下讲话稿
2014/09/10 职场文书
初中重阳节活动总结
2015/05/05 职场文书
html用代码制作虚线框怎么做? dw制作虚线圆圈的技巧
2022/12/24 HTML / CSS