php魔术方法——属性重载方法
php有一类很神奇的方法,这些方法是保留方法,通常不会在外部被显式调用,他们使用双下划线(__)开头,他们被称为魔术方法(Magic Methods)。php官方也不建议定义其他双下划线开头的方法。
这次介绍属性重载方法:get/set/isset/unset
public void __set ( string $name , mixed $value ) public mixed __get ( string $name ) public bool __isset ( string $name ) public void __unset ( string $name )
这些方法触发的时机,都是在访问不可访问的属性的时候。
如以下:
<?php class Cls{ private $a = 0;
protected $b = 1;
public $c = 2;
var $d = 3; private $_properties = array(0); public function __set($name, $value){
echo __METHOD__ . ' is called! ' . json_encode(func_get_args()) . "\n";
return $this->_properties[$name] = $value;
} public function __get($name){
echo __METHOD__ . ' is called! ' . json_encode(func_get_args()) . "\n";
return $this->_properties[$name];
} public function __isset($name){
echo __METHOD__ . ' is called! ' . json_encode(func_get_args()) . "\n";
return isset($this->_properties[$name]);
} public function __unset($name){
echo __METHOD__ . ' is called! ' . json_encode(func_get_args()) . "\n";
unset($this->_properties[$name]);
} public function dump(){
echo "====================== DUMP START ====================\n";
echo <<<STR
a: $this->a
b: $this->b
c: $this->c
d: $this->d\n
STR;
foreach($this->_properties as $k => $v){
echo <<<STR
Property $k: $v\n
STR;
} echo "====================== DUMP STOP =====================\n"; }
}
$string = 'abcdef';
$obj = new Cls(); $list = array('isset', 'get', 'set', 'isset', 'unset', 'isset');
$obj->dump();
foreach($list as $method){
for($i = 0 ; $i < strlen($string) ; $i ++){
$char = $string{$i};
echo "------ $method : $char ------\n";
switch($method){
case 'isset':
echo json_encode($tmp = isset($obj->$char)) . "\n";
break;
case 'get':
echo json_encode($tmp = $obj->$char) . "\n";
break;
case 'set':
echo json_encode($tmp = $obj->$char = $char . "-val") . "\n";
break;
case 'unset':
unset($obj->$char);
break;
default:
break;
}
}
$obj->dump();
}
结果输出:
====================== DUMP START ====================
a: 0
b: 1
c: 2
d: 3
Property 0: 0
====================== DUMP STOP =====================
------ isset : a ------
Cls::__isset is called! ["a"]
false
------ isset : b ------
Cls::__isset is called! ["b"]
false
------ isset : c ------
true
------ isset : d ------
true
------ isset : e ------
Cls::__isset is called! ["e"]
false
------ isset : f ------
Cls::__isset is called! ["f"]
false
====================== DUMP START ====================
a: 0
b: 1
c: 2
d: 3
Property 0: 0
====================== DUMP STOP =====================
------ get : a ------
Cls::__get is called! ["a"]
null
------ get : b ------
Cls::__get is called! ["b"]
null
------ get : c ------
2
------ get : d ------
3
------ get : e ------
Cls::__get is called! ["e"]
null
------ get : f ------
Cls::__get is called! ["f"]
null
====================== DUMP START ====================
a: 0
b: 1
c: 2
d: 3
Property 0: 0
====================== DUMP STOP =====================
------ set : a ------
Cls::__set is called! ["a","a-val"]
"a-val"
------ set : b ------
Cls::__set is called! ["b","b-val"]
"b-val"
------ set : c ------
"c-val"
------ set : d ------
"d-val"
------ set : e ------
Cls::__set is called! ["e","e-val"]
"e-val"
------ set : f ------
Cls::__set is called! ["f","f-val"]
"f-val"
====================== DUMP START ====================
a: 0
b: 1
c: c-val
d: d-val
Property 0: 0
Property a: a-val
Property b: b-val
Property e: e-val
Property f: f-val
====================== DUMP STOP =====================
------ isset : a ------
Cls::__isset is called! ["a"]
true
------ isset : b ------
Cls::__isset is called! ["b"]
true
------ isset : c ------
true
------ isset : d ------
true
------ isset : e ------
Cls::__isset is called! ["e"]
true
------ isset : f ------
Cls::__isset is called! ["f"]
true
====================== DUMP START ====================
a: 0
b: 1
c: c-val
d: d-val
Property 0: 0
Property a: a-val
Property b: b-val
Property e: e-val
Property f: f-val
====================== DUMP STOP =====================
------ unset : a ------
Cls::__unset is called! ["a"]
------ unset : b ------
Cls::__unset is called! ["b"]
------ unset : c ------
------ unset : d ------
------ unset : e ------
Cls::__unset is called! ["e"]
------ unset : f ------
Cls::__unset is called! ["f"]
====================== DUMP START ====================
Cls::__get is called! ["c"]
Cls::__get is called! ["d"]
a: 0
b: 1
c:
d:
Property 0: 0
====================== DUMP STOP =====================
------ isset : a ------
Cls::__isset is called! ["a"]
false
------ isset : b ------
Cls::__isset is called! ["b"]
false
------ isset : c ------
Cls::__isset is called! ["c"]
false
------ isset : d ------
Cls::__isset is called! ["d"]
false
------ isset : e ------
Cls::__isset is called! ["e"]
false
------ isset : f ------
Cls::__isset is called! ["f"]
false
====================== DUMP START ====================
Cls::__get is called! ["c"]
Cls::__get is called! ["d"]
a: 0
b: 1
c:
d:
Property 0: 0
====================== DUMP STOP =====================
特别强调,当这个属性不存在(基于当前访问权限)的时候,才会触发这些方法。因此严重建议使用确定的键值进行get/set处理,特别是对应的键值不要有访问权限问题,如上例中的a和b,会导致在类内部、类外部、子类内处理的方式不同,开发时产生不可预知的返回值,极易产生bug。
empty方法不能调用属性重载方法。
$tmp = $obj->$char = $char . "-val"
此例中,__set自身的返回值将被忽略,同样__get也不会被调用。
此外:属性重载方法必须声明为public,同时参数不能使用引用传递,静态属性不能通过这些方法重载,这些方法也不能被声明为static。
当然,使用魔术方法的时候,也会对反射系统造成影响。
php魔术方法——属性重载方法的更多相关文章
- Python中类的方法属性与方法属性的动态绑定
最近在学习python,纯粹是自己的兴趣爱好,然而并没有系统地看python编程书籍,觉得上面描述过于繁琐,在网站找了一些学习的网站,发现廖雪峰老师的网站上面的学习资源很不错,而且言简意赅,提取了一些 ...
- JAVA笔记2__类/封闭性/构造方法/方法的重载/匿名对象
public class Main { public static void main(String[] args) { Chicken c1 = new Chicken(); Chicken c2 ...
- Java中方法的重载和重置(覆盖)的区别
简单来说,重载就是在同一类中允许同时存在一个以上的同名方法,只要这些方法的参数个数或类型不同即可,而重置(覆盖)是子类重新定义父类中己经定义的方法,即子类重写父类方法. 方法的重载 方法的重载就是在同 ...
- python中类中属性和方法的具体定义方法和使用
1. Python中类中特性分成属性和方法 属性和方法都分为私有和公有的,私有的只可以在本类中使用外部是无法访问的 2. 定义属性(成员变量)的语法格式(公有属性/私有属性) class 类名: de ...
- Java学习笔记17---成员方法的重载与重写
重载是指,一个类中定义了一个成员方法后,通过修改参数个数.参数类型或参数顺序,重新实现该方法,则这两个方法互为对方的重载方法. 重写是指,子类重新实现父类的成员方法. 重载后的方法,与原方法相比: ( ...
- Day1 方法的重载
方法的重载 方法的标识符包括: 1.方法名称 2.方法的参数(参数类型和参数的数量) 方法的重载:方法名称相同 但是方法参数不同(1.参数类型不同 2.参数类型相同 但是参数个数不同 3.类型和个 ...
- php之属性重载和方法重载
<?php /** * * @authors Your Name (you@example.org) * @date 2016-06-13 20:40:19 * @version $Id$ */ ...
- 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间
[源码下载] 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间 作者:webabcd 介绍速战速决 之 PHP 动态地创 ...
- java中的对象,类。与 方法的重载。
对象: 一切皆为对象.对象包括两部分内容:属性(名词形容词),行为(动词).对象和对象之间是有关系的: 派生,关联,依赖. 类: 对同一类别的众多对象的一种抽象.类,还是用来生成对象的一种模板,对象是 ...
随机推荐
- 关于tcc、tlink的编译链接机制的研究
1.学习过程 在c:\下建立文件夹c,并将编译器tcc.exe.连接器tlink.exe.相关文件c0s.obj.cs.lib.emu.lib.maths.lib放入文件夹中. 要搭建一个简单的C语言 ...
- java中gson的简单使用
把从数据库中查询的记录以JSON格式返回给客户端,在这里使用gson-2.2.4.jar包. 代码结构如下: 数据库结构如下: (1)User.java public class User { pri ...
- 关于51单片机P0口的结构及上拉问题
1.P0作为地址数据总线时,V1和V2是一起工作的,构成推挽结构.高电平时,V1打开,V2截止:低电平时,V1截止,V2打开.这种情况下不用外接上拉电阻.而且,当V1打开,V2截止,输出高电平的时候, ...
- 说说自己对RESTful API的理解s
REST不是英文上的rest单词,其英文缩写为presentational State Transfer ,直译为表现状态转移,咋看起来很学术,不懂,其实不用去死抠这个词的意思.REST是一种约束和架 ...
- linux 信号signal和sigaction理解
今天看到unp时发现之前对signal到理解实在浅显,今天拿来单独学习讨论下. signal,此函数相对简单一些,给定一个信号,给出信号处理函数则可,当然,函数简单,其功能也相对简单许多,简单给出个函 ...
- ortp使用详解2
五:数据的接收和发送 1. 发送过程: 应用发送数据时调用接口 rtp_session_send_with_ts 完成.参数为会话句柄,数据缓冲区地址,数据长度以及应用当前的时间戳.在该接口中,会先调 ...
- LeeCode-String to Integer (atoi)
Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input cases. ...
- hadoop2.2.0伪分布模式64位安装
hadoop2.2.0伪分布模式64位安装用到的软件:jdk-6u45-linux-x64.bin,hadoop-2.2.0.x86_64.tar.gz 修改主机名vim /etc/sysconfig ...
- linux中cat、more、less、tail、head命令
cat命令功能用于显示整个文件的内容单独使用没有翻页功能因此经常和more命令搭配使用,cat命令还有就是将数个文件合并成一个文件的功能. more命令功能:让画面在显示满一页时暂停,此时可按空格健继 ...
- i&1、负数二进制
if(i&1==1) 表示 如果是 奇数 则...i&1 -- 按位与运算,取 2进制整数 i 的最低位,如果最低位是1 则得1,如果最低位是0 则得0. 奇数 i 的最低位 是1,偶 ...