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的网址
Nov 25 PHP
PHP正则表达式替换站点关键字链接后空白的解决方法
Sep 16 PHP
php+mysql实现数据库随机重排实例
Oct 17 PHP
PHP输出图像imagegif、imagejpeg与imagepng函数用法分析
Nov 14 PHP
php mysql_real_escape_string addslashes及mysql绑定参数防SQL注入攻击
Dec 23 PHP
Laravel实现搜索的时候分页并携带参数
Oct 15 PHP
关于laravel-admin ueditor 集成并解决刷新的问题
Oct 21 PHP
laravel 解决crontab不执行的问题
Oct 22 PHP
TP5框架安全机制实例分析
Apr 05 PHP
Thinkphp 框架扩展之Widget扩展实现方法分析
Apr 23 PHP
PHP如何通过带尾指针的链表实现'队列'
Oct 22 PHP
php远程请求CURL实例教程(爬虫、保存登录状态)
Dec 10 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
Android App中DrawerLayout抽屉效果的菜单编写实例
2016/03/21 PHP
php同时使用session和cookie来保存用户登录信息的实现代码
2016/05/13 PHP
在Laravel5.6中使用Swoole的协程数据库查询
2018/06/15 PHP
thinkphp5框架扩展redis类方法示例
2019/05/06 PHP
Asp.net下使用Jquery Ajax传送和接收DataTable的代码
2010/09/12 Javascript
jQuery初学:find()方法及children方法的区别分析
2011/01/31 Javascript
JS模拟面向对象全解(二、类型与赋值)
2011/07/13 Javascript
jquery click([data],fn)使用方法实例介绍
2013/07/08 Javascript
jQuery实现鼠标滑过遮罩并高亮显示效果
2013/07/16 Javascript
8个超实用的jQuery功能代码分享
2015/01/08 Javascript
Bootstrap每天必学之折叠(Collapse)插件
2016/04/25 Javascript
jQuery实现ajax的叠加和停止(终止ajax请求)
2016/08/08 Javascript
js实现砖头在页面拖拉效果
2020/11/20 Javascript
vue项目中使用ueditor的实例讲解
2018/03/05 Javascript
jQuery实现表格隔行换色
2018/09/01 jQuery
VuePress 静态网站生成方法步骤
2019/02/14 Javascript
vue el-tree 默认展开第一个节点的实现代码
2020/05/15 Javascript
一分钟学会JavaScript中的try-catch
2020/12/14 Javascript
[42:32]DOTA2上海特级锦标赛B组资格赛#2 Fnatic VS Spirit第二局
2016/02/27 DOTA
[02:11]DOTA2上海特级锦标赛主赛事第二日RECAP
2016/03/04 DOTA
python快速排序代码实例
2013/11/21 Python
python字符串的拼接方法总结
2019/11/18 Python
Pytorch 使用CNN图像分类的实现
2020/06/16 Python
使用Python制作一个数据预处理小工具(多种操作一键完成)
2021/02/07 Python
CSS3制作苹果风格键盘特效
2015/02/26 HTML / CSS
美国运动鞋和运动服零售商:Footaction
2017/04/07 全球购物
劲霸男装广告词
2014/03/21 职场文书
计算机毕业生自荐信范文
2014/03/23 职场文书
本科毕业生自荐信
2014/06/02 职场文书
2014和解协议书范文
2014/09/15 职场文书
党支部先进事迹材料
2014/12/24 职场文书
搞笑结婚保证书
2015/05/08 职场文书
原来闭幕词是这样写的呀!
2019/07/01 职场文书
想要创业,那么你做好准备了吗?
2019/07/01 职场文书
mysql中DCL常用的用户和权限控制
2022/03/31 MySQL
使用compose函数优化代码提高可读性及扩展性
2022/06/16 Javascript