php 魔术函数使用说明


Posted in PHP onFebruary 21, 2010

什么是魔术函数?
对于__开头的函数就命名为魔术函数, 此类函数都在特定的条件下触发的.比如: __set() __get()等
在设置或取不存在的属性时候触发.
有那些魔术函数呢?
总的来说, 有下面几个魔术函数
__construct() __destruct() __get() __set() __isset() __unset() __call() __callStatic()
__sleep() __wakeup() __toString() __set_state() __clone() __autoload()
__construct()当实例化一个对象的时候,这个对象的这个方法首先被调用。
__destruct()当删除一个对象或对象操作终止的时候,调用该方法。

class test1 { 
public function __construct() { 
var_dump(__function__); 
} 
public function __destruct() { 
var_dump(__function__); 
} 
} 
$t1 = new test1 ; 
unset($t1);

__get当试图读取一个并不存在的属性的时候被调用。
__set当试图向一个并不存在的属性写入值的时候被调用。
__isset当试图检测一个并不存在的属性时候被调用。
__unset当试图取消一个并不存在的属性时候被调用。
class test2 { 
public $name3; 
public function __set($key, $value) { 
var_dump(__function__. ' 
KEY:' 
.$key.' 
Value:' 
.$value); 
} 
public function __get($key) { 
var_dump(__function__. 'KEY:'.$key); 
} 
public function __isset($key) { 
var_dump(__function__. ' KEY:'.$key); 
} 
public function __unset($key) { 
var_dump(__function__. ' KEY:'.$key); 
} 
} 
$t =new test2 ; 
$t->name = "steven"; 
$t->name2; 
$t->name3; 
isset($t->name2); 
isset($t->name3); 
unset($t->name4);

__sleep当进行序列化对象时候调用
__wakeup当进行反序列对象时候调用
需要注意一点:
1. __sleep()必须返回一个数组或者对象(一般返回的是$this),返回的值将会被用来做为序列化的
值。
如果不返回这个值,则序列化失败。这也意味着反序列化将不会触发__wakeup事件。
2. 序列化会保存默认赋值的属性.如果要通过实例化赋值的内容,则需要属性在__sleep()返回数组的
指定.
如$id与$id2的区别.
class test3 { 
public $name = "steven"; 
public $id = "1"; public $id2; 
public function __sleep() { 
var_dump(__function__); // 序列化不成功.没有返回值.反序列也失败 // 
return array("name"); // 序列化成功.有返回值.反序列成功.id2属性能被恢复 // 
return array("name", "id2");// 序列化成功.有返回值.反序列成功.id2属性不能被恢复 
return array("name"); } 
public function testEcho() { 
var_dump($this->name); 
var_dump($this->id); 
var_dump($this->id2); 
} 
public function __wakeup() { 
var_dump(__function__); 
$this->testEcho(); 
} 
} 
$t3= new test3 ; 
$t3->id2 = uniqid(); 
$t3s = serialize($t3); 
unserialize($t3s);

__toString当直接打印一个对象的时候,这个方法将会被调用
class test4 { 
public function __toString() { 
return "toString"; 
} 
} 
$t4 = new test4(); 
echo $t4; 
print $t4; 
var_dump($t4); 
print_r($t4);

__call($func, $param) 当尝试调用一个不存在的方法的时候被调用.
这个方法必须有两个参数,第一个为调用的方法名,第二个是一个被调用方法的参数数组。
需要注意的是,当你在一个子类调用父类的private的方法,或者在实例里调用类的非protect方法的
时候,并不会调用__call()
class test5 { 
public function __call($func, $param) { 
var_dump('Function:'.$func); 
var_dump($param); 
} 
} 
$t5 = new test5; 
$t5->echoTest('xx','xx','xx');

__callStatic()当尝试调用一个不存在的静态方法的时候被调用
这个方法必须有两个参数,第一个为调用的方法名,第二个是一个被调用方法的参数数组。
在PHP5.3中出现
class test51 { 
public function __callStatic($fun, $param) { 
var_dump('Function:'.$func); 
var_dump($param); 
} 
} 
test51::test('xx','xx','xx');

__set_state()当用var_export导出实例的时候被调用.此方法有一个参数,为包含所导出的实例的所
有成员属性的一个数组
class test6 { 
public function __set_state($arr){ 
var_dump($arr); 
} 
} 
$t6 = new test6; 
$t6->age = "12"; 
var_export($t6, true); 
var_export($t6); 
eval(' 
$b=' 
.var_export($t6,true).';'); 
print_r($b);

__clone()当克隆实例时候被调用.
注意:
1.在php5里,对象间的赋值总是以地址引用来传递的.
2.如果要以实际值来传递,则需要用到clone关键词
3.clone的只是实例。如果实例中的某个成员属性也是个实例,那么这个成员属性还是会以引用方法被
传递到新的实例。
// 对象间的赋值总是以地址引用来传递的. $t71 $t72的age属性是一样的.
class test71 { 
public $age = 10; 
} 
$t71 = new test71(); 
$t72 = $t71 ; 
var_dump($t71->age) ; 
$t71->age =12 ; 
var_dump($t71->age) ; 
var_dump($t72->age) ; // 如果要以实际值来传递,则需要用到clone关键词 $t73 = clone $t71; $t71->age = 13 ; var_dump($t71->age) ; 
var_dump($t73->age) ; // 如果实例中的某个成员属性也是个实例,那么这个成员属性还是会以引用方法被传递到新的实例。

class test74 { 
public $age = 10; 
public $sub = null; 
} 
class test75 { 
public $age = 11; 
} 
$i = new test74; 
$i->sub = new test75(); 
$i1 =clone $i; 
var_dump($i1->sub->age); 
$i->sub->age = 12; 
var_dump($i1->sub->age);

// $i 和$i1虽然不是指向同一个实例,但是它们的成员属性$sub却是指向同一个实例。这时候,我们必须借
助__clone这个方法来对$sub进行复制。 // $i2和$3指向不同实例.成员属性$sub也指向不同实例.
class test76 { 
public $age = 10; 
public $sub = null; 
public function __clone() { 
$this->sub = clone $this->sub; 
} 
} 
$i2 = new test76(); 
$i2->sub = new test75(); 
$i3 = clone $i2; 
$i2->sub->age = 15 ; 
var_dump($i3->sub->age);

__autoload()函数.当创建一个实例化的时候,如果对应的类不存在,则会被调用
function __autoload($class) { 
 if ( $class == "test8" ){ 
require_once dirname(__FILE__).'/class8.php';  
} 
} 
spl_autoload(); 
$t8 = new test8; 
var_dump($t8->age);
PHP 相关文章推荐
PHP取得一个类的属性和方法的实现代码
May 22 PHP
PHP语法自动检查的Vim插件
Aug 11 PHP
windows中为php安装mongodb与memcache
Jan 06 PHP
ThinkPHP3.2.3数据库设置新特性
Mar 05 PHP
php中判断数组相等的方法以及数组运算符介绍
Mar 30 PHP
PHP中使用hidef扩展代替define提高性能
Apr 09 PHP
PHP 双链表(SplDoublyLinkedList)简介和使用实例
May 12 PHP
PHP使用curl模拟post上传及接收文件的方法
Mar 04 PHP
java微信开发之上传下载多媒体文件
Jun 24 PHP
php实现xml转换数组的方法示例
Feb 03 PHP
yii2.0整合阿里云oss上传单个文件的示例
Sep 19 PHP
Codeigniter里的无刷新上传的实现代码
Apr 14 PHP
php microtime获取浮点的时间戳
Feb 21 #PHP
PHP+ajax 无刷新删除数据
Feb 20 #PHP
php 读取文件乱码问题
Feb 20 #PHP
判断是否为指定长度内字符串的php函数
Feb 16 #PHP
支持数组的ADDSLASHES的php函数
Feb 16 #PHP
php htmlspecialchars加强版
Feb 16 #PHP
php 数组二分法查找函数代码
Feb 16 #PHP
You might like
php mssql 数据库分页SQL语句
2008/12/16 PHP
php中实现简单的ACL 完结篇
2011/09/07 PHP
php实现执行某一操作时弹出确认、取消对话框
2013/12/30 PHP
分享PHP计算两个日期相差天数的代码
2015/12/23 PHP
TP5框架实现一次选择多张图片并预览的方法示例
2020/04/04 PHP
简单的JS多重继承示例
2008/03/13 Javascript
纯JS实现的批量图片预览加载功能
2011/08/14 Javascript
获取下拉列表框的值是数组,split,$.inArray示例
2013/11/13 Javascript
JS关键字球状旋转效果的实例代码
2013/11/29 Javascript
用jquery.sortElements实现table排序
2014/05/04 Javascript
QQ空间顶部折页撕开效果示例代码
2014/06/15 Javascript
vue组件初学_弹射小球(实例讲解)
2017/09/06 Javascript
vue如何通过id从列表页跳转到对应的详情页
2018/05/01 Javascript
CSS3 动画卡顿性能优化的完美解决方案
2018/09/20 Javascript
微信小程序class封装http代码实例
2019/08/24 Javascript
生成无限制的微信小程序码的示例代码
2019/09/20 Javascript
小程序简单两栏瀑布流效果的实现
2019/12/18 Javascript
Python NumPy库安装使用笔记
2015/05/18 Python
浅析Python中的多条件排序实现
2016/06/07 Python
python3中dict(字典)的使用方法示例
2017/03/22 Python
Django中使用第三方登录的示例代码
2018/08/20 Python
Python玩转Excel的读写改实例
2019/02/22 Python
django的model操作汇整详解
2019/07/26 Python
django 数据库连接模块解析及简单长连接改造方法
2019/08/29 Python
python遍历文件目录、批量处理同类文件
2019/08/31 Python
Python使用monkey.patch_all()解决协程阻塞问题
2020/04/15 Python
python如何保存文本文件
2020/06/07 Python
用python查找统一局域网下ip对应的mac地址
2021/01/13 Python
党员学习十八大感想
2014/01/17 职场文书
学校志愿者活动总结
2014/06/27 职场文书
学校法制宣传日活动总结
2014/11/01 职场文书
党员承诺书范文2015
2015/04/27 职场文书
乡镇党建工作总结2015
2015/05/19 职场文书
建党伟业电影观后感
2015/06/01 职场文书
2016年5月份红领巾广播稿
2015/12/21 职场文书
Python爬取科目四考试题库的方法实现
2021/03/30 Python