PHP中 对象自动调用的方法:__set()、__get()、__tostring()

总结:

 (1)__get($property_name):获取私有属性$name值时,此对象会自动调用该方法,将属性name值传给参数$property_name,通过这个方法的内部

                                             执行,返回我们传入 的私有属性的值。

 (2)__set($property_name, $value):直接给私有属性赋值时,此对象会自动调用该方法,把属性比如name传给$property_name, 把要赋的值

                                                         “zhangsan”传给$value,通过这个方法的执行,达到赋值的目的。

 (3)__tostring()                : 当直接输出句柄(可以理解为一个实例)时,会自动执行__tostring()方法。

 

1.__set()与__get().

         一般来说,总是把类的属性定义为private,这更符合现实的逻辑。但是,对属性的读取和赋值操作是非常频繁的,因此在 PHP5中,预定义了两个函数

“__get()”和“__set()”来获取和赋值其属性,以及检查属性的“__isset()”和删除属性的方法 “__unset()”。


       我们为每个属性做了设置和获取的方法,在PHP5中给我们提供了专门为属性设置值和获 取值的方法,“__set()”和“__get()”这两个方法,这两个方法不是默认存在的,

而是我们手工添加到类里面去的,像构造方法 (__construct())一样, 类里面添加了才会存在,可以按下面的方式来添加这两个方法,当然也可以按个人的风格来添加:

//__get()方法用来获取私有属性
public function __get($property_name)
{if(isset($this->$property_name)){return($this->$property_name);}else{return(NULL);}
}//__set()方法用来设置私有属性
public function __set($property_name, $value){
$this->$property_name = $value;
}

__get()方法:这个方法用来获取私有成员属性值的,有一个参数,参数传入 你要获取的成员属性的名称,返回获取的属性值,这个方法不用我们手工的去调用,因为我们也可以把这个方法做成私有的方法,是在直接获取私有属性的时候对象 自动调用的。因为私有属性已经被封装上了,是不能直接获取值的(比如:“echo $p1->name”这样直接获取是错误的),但是如果你在类里面加上了这个方法,在使用“echo $p1->name”这样的语句直接获取值的时候就会自动调用__get($property_name)方法,将属性name传给参 数$property_name,通过这个方法的内部执行,返回我们传入的私有属性的值。如果成员属性不封装成私有的,对象本身就不会去自动调用这个方 法。


__set()方法:这个方法用来为私有成员属性设置值的,有两个参数,第一个参数为你要为设置值的属性名,第二个参数是要给属性设置的值, 没有返回值。这个方法同样不用我们手工去调用,它也可以做成私有的,是在直接设置私有属性值的时候自动调用的,同样属性私有的已经被封装上

了, 如果没有__set()这个方法,是不允许的,比如:$this->name=‘zhangsan’, 这样会出错,但是如果你在类里面加上了__set($property_name, $value)这个方法,在直接给私有属性赋值的时候,就会自动调用它,把属性比如name传给$property_name, 把要赋的值“zhangsan”传给$value,通过这个方法的执行,达到赋值的目的。如果成员属性不封装成私有的,对象本身就不会去自动调用这个方 法。为了不传入非法的值,还可以在这个方法给做一下判断。代码如下:

<?php
class Person {//下面是人的成员属性, 都是封装的私有成员private $name; //人的名子private $sex; //人的性别private $age; //人的年龄//__get()方法用来获取私有属性public function __get($property_name) {echo "在直接获取私有属性值的时候,自动调用了这个__get()方法<br>";if (isset ( $this->$property_name )) {return ($this->$property_name);} else {return (NULL);}}//__set()方法用来设置私有属性public function __set($property_name, $value) {echo "在直接设置私有属性值的时候,自动调用了这个__set()方法为私有属性赋值<br>";$this->$property_name = $value;}
}

$per=new person();
$per->name="shirayner"; //此时$per自动调用__set($property_name, $value)方法
echo $per->name; //此时$per自动调用__get($property_name)方法

?>

2.__tostring()

TOstring(在这里故意这么写,是要说明PHP中方法不区分大小写,但实际开发中还需要注意规范)。当进行测试时,需要知道是否得出正确的数据。比如打印一个对象时,看看这个对象都有哪些属

性,其值是什么,如果类定义了toString方法,就能在测试时,echo打印对象体,对象就会自动调用它所属类定义的toString方法,格式化输出这个对象所包含的数据。如果没有这个方法,那么echo一个对
象将报错,例如“Catchable fatal error:Object of class Account could not be converted tostring”语法错误,实际上这是一个类型匹配失败错误。不过仍然可以用print_r()
和var_dump()函数输出一个对象。当然,toString是可以定制的,所提供的信息和样式更丰富。
<?php
class Account{
public $user=1;
private $pwd=2;
// 自定义的格式化输出方法
public function toString(){
return "当前对象的用户名是{$this->user},密码是{$this->pwd}";
}
}
$a=new Account();
echo $a;
echo PHP_EOL;
print_r($a);

      运行这段代码发现,使用toString方法后,输出的结果是可定制的,更易于理解。实际上,PHP的toString魔术方法的设计原型来源于 Java。Java中也有这么一个方法,而且在Java中,这个方法被大量使用,对于调试程序比较方便。实际上,toString方法也是一种序列化,我 们知道PHP自带serialize/unserialize也是进行序列化的,但是这组函数序列化时会产生一些无用信息,如属性字符串长度,造成存储空 间的无谓浪费。因此,可以实现自己的序列化和反序列化方法,或者json_encode/json_decode也是一个不错的选择。

为什么直接echo一个对象就会报语法错误,而如果这个对象实现toString方法后就可以直接输出呢?原因很简单,echo本来可以打印一个对 象,而且也实现了这个接口,但是PHP对其做了个限制,只有实现toString后才允许使用。从下面的PHP源代码里可以得到验证:

ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMP|VAR|CV, ANY)
{
zend_op *opline = EX(opline);
zend_free_op free_op1;
zval z_copy;
zval *z = GET_OP1_ZVAL_PTR(BP_VAR_R);
// 此处的代码预留了把对象转换为字符串的接口
if (OP1_TYPE != IS_CONST &&
Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
zend_print_variable(&z_copy);
zval_dtor(&z_copy);
} else {
zend_print_variable(z);
}
 
FREE_OP1();
ZEND_VM_NEXT_OPCODE();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/296540.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

xhprof php性能分析工具

先安装libpng*下载安装xhprofwget http://pecl.php.net/get/xhprof-0.9.2.tgztar zxf xhprof-0.9.2.tgzcd xhprof-0.9.2cp -r xhprof_html xhprof_lib cd extensionphpize./configuremakemake install编辑php.ini[xhprof]extensionxhprof.so;; directory used by default imple…

matlab中给图像加几个矩形框_没想到!PPT中的这个效果,用好了,简直就是渣图美化器...

相信大家一定看到过&#xff0c;透过磨砂玻璃呈现在眼前的景色&#xff0c;是不是有种朦胧美&#xff1f;其实&#xff0c;在PPT中你也可以复刻出这样的效果。例如&#xff0c;这样的PPT页面&#xff1a;把背景虚化掉&#xff0c;更加突出主题。你想知道PPT中的磨砂效果&#x…

【转贴】mysql导入数据load data infile用法

mysql导入数据load data infile用法 基本语法&#xff1a;load data [low_priority] [local] infile file_name txt [replace | ignore]into table tbl_name[fields[terminated byt][OPTIONALLY] enclosed by ][escaped by\ ]][lines terminated byn][ignore number lines][(co…

宝贝,我帮你清了购物车哦!

1 一场意外让本不富裕的女朋友雪上加霜甚至还回复了单身▼2 外甥女去参加舅舅的婚礼发现账本上没有她的名字于是写上自己的名字并随了兜里所有的钱人情世故整的明明白白▼3 我感觉再多吹几首他们就能复合......▼4 在家隔离第N天果然天下沙雕是一家▼5 我猜中了开头但没猜…

Dapr牵手.NET学习笔记:Actor小试

Actor模型是一种避免线程共享数据&#xff0c;相同Actor实体串行化的方案&#xff0c;所以不便dapr的其他功能&#xff0c;几乎都是非编程入侵的&#xff0c;相反&#xff0c;Dapr Acror深度定制的&#xff0c;关于Actor&#xff0c;.net中有一些通用框架&#xff0c;比如Akka.…

认识Linux下的各种系统服务

只要是linux系统、不管什么发行版本&#xff0c;都有以下的系统服务。本文将对这些服务逐一进行说明。推荐花一些时间来了解这些服务的作用&#xff0c;以便清楚的知道自己该使用哪些服务。 NetworkManager, NetworkManagerDispatcherNetworkManager是一个后台服务程序&#xf…

黄聪:wordpress如何开启文章格式post format

发现很多“古老”的WordPress主题使用量非常大&#xff0c;虽然部分也在随着WordPress版本的升级而“升级”&#xff0c;只不过是修复了bug而已&#xff0c;wordpress的新特性并没有使用。而且多数国内的wordpress主题制作者&#xff0c;也都是在这些主题的基础上进行创作&…

11没有源码注释_我们为什么要看源码、应该如何看源码?

看源码的意义看源码只是一种方法、手段&#xff0c;而不是目的。我也曾经给自己制定过“阅读xxx源码”的目标&#xff0c;现在看起来真的很蠢&#xff0c;一点不smart&#xff08;specific、measurable、attainable、relevant、time-bound&#xff09;。只有搞清楚了阅读代码的…

如果你没空读书,就一定要来看看这8个公众号!

全世界只有3.14 % 的人关注了爆炸吧知识不管世界变化多块&#xff0c;阅读仍是个不过时的动作。今天就为大家推荐几个优质公众号&#xff0c;从社会热点、读书成长、生活新知&#xff0c;你的碎片化时间&#xff0c;我们包了&#xff01;一起来看看呀~♥长按二维码&#xff0c;…

03Prism WPF 入门实战 - Region

1.概要源码及PPT地址&#xff1a;https://github.com/JusterZhu/wemail视频地址&#xff1a;https://www.bilibili.com/video/BV1KQ4y1C7tg?sharesourcecopyweb&#xff08;1&#xff09;Prism概览Application&#xff1a;我们开发应用程序&#xff0c;初始化Bootstrapper。Bo…

CentOS利用crontab执行计划任务

walker的需求是每天1点钟的时候&#xff0c;执行一个shell脚本&#xff0c;下面记录walker用到的基本功能。1、安装yum install crontabs2、服务相关/sbin/service crond status #查看任务状态 /sbin/service crond start #启动服务 /sbin/service crond stop …

10月Web服务器调查:Apache下降 Ngnix攀升

来自netcraft的消息&#xff0c;在2010年10月份的Web服务器市场调查中&#xff0c;在232,839,963个网站中&#xff0c;仍有69.8%的站点在使用 Apache服务器&#xff0c;相比于上个月&#xff0c;其市场份额增长了大约1个百分点&#xff0c;Ngnix也有较小幅度的增长&#xff0c;…

四元数左乘右乘_四元数、欧拉角学习笔记个人理解

一、背景知识&#xff1a;点乘、叉乘复数的点乘&#xff1a;(aibjck)•(xiyjzk)-(axbycz)复数的叉乘&#xff1a;(aibjck)(xiyjzk)(ax)ii(ay)ij(az)ik(bx)ji(by)jj(bz)jk(cx)ki(cy)kj(cz)kkijk三轴定义如上图所示。满足右手螺旋定则&#xff1a;(这个不是太明白&#xff0c;但是…

Python深度学习029:pytorch中常用的模块或方法

PyTorch是一个广泛使用的深度学习库,提供了许多用于构建和训练神经网络的模块和方法。下面是一些PyTorch中常用的模块和方法的简要介绍: PyTorch常用模块和方法 torch 用途:PyTorch的基础模块,提供了多种数学运算功能。常用方法: torch.tensor():创建张量torch.randn():…

struts2 标签不能使用EL 表单式

<c:forEach items"${requestScope.dataitemList}" var"item" varStatus"i" >//使用c:set 标签注意使用Scope属性 不然在request里面取不到值。 <s:select id"type%{#attr.i.index}" name"dataitemType" list"…

【转载】Android设计中的.9.png

转载自&#xff1a;腾讯ISUX (http://isux.tencent.com/android-ui-9-png.html) 在Android的设计过程中&#xff0c;为了适配不同的手机分辨率&#xff0c;图片大多需要拉伸或者压缩&#xff0c;这样就出现了可以任意调整大小的一种图片格式“.9.png”。这种图片是用于Android开…

如果你没空看书,我强烈建议你做这件事!

知乎上有个高赞问题&#xff1a;有哪些书看完后&#xff0c;会让人后悔没早看到&#xff1f;答案各有不一、包罗万象。但有一点&#xff0c;大家达成了共识&#xff1a;要多读书。人生漫长&#xff0c;而我们都不会是一成不变的&#xff0c;真正决定人与人之间的差距的&#xf…

为什么应该在业务层实现管道模式,而不用ASP.NET Core Middleware实现 | 2点原因和实现方式...

前言ASP.NET Core的Middleware&#xff08;中间件&#xff09;就是使用了管道模式&#xff1a;Request&#xff08;请求&#xff09;在管道中传递&#xff0c;依次经过管道中的每一个MiddleWare进行处理。MiddleWare就像一层层的“滤网”&#xff0c;过滤所有的请求和响应。这种…

McAfee:较之中国美国黑客才最令人害怕

据McAfee研究发现美国是最有可能的网络攻击来源&#xff0c;而不是人们印象中广泛认为的中国或者俄罗斯。 McAfee进行了这么一项研究&#xff0c;组织来自各个国家的600位IT安全主管进行讨论&#xff0c;为他们最关注的互联网安全问题定级和归类&#xff0c;大部分报告都是符合…

缓存在哪里_什么是MyBatis缓存技术

MyBatis缓存引言在一个Web项目中&#xff0c;查询数据库中的操作算是一个非常常用的操作&#xff0c;但是有些数据会被经常性的查询&#xff0c;而每一次都去数据库中查询这些重复的数据&#xff0c;会很消耗数据库的资源&#xff0c;同时使得查询效率也很低&#xff0c;而 MyB…