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 zend解密软件绿色版测试可用
Apr 14 PHP
完美解决PHP中文乱码
Nov 26 PHP
php设计模式 Chain Of Responsibility (职责链模式)
Jun 26 PHP
实例讲解PHP面向对象之多态
Aug 20 PHP
Ubuntu12下编译安装PHP5.3开发环境
Mar 27 PHP
ThinkPHP安装和设置
Jul 27 PHP
解决php表单重复提交实现方法
Sep 29 PHP
双冒号 ::在PHP中的使用情况
Nov 05 PHP
php实现的递归提成方案实例
Nov 14 PHP
PHP基于socket实现的简单客户端和服务端通讯功能示例
Jul 10 PHP
Joomla框架实现字符串截取的方法示例
Jul 18 PHP
laravel5.6 框架操作数据 Eloquent ORM用法示例
Jan 26 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中MVC的开发经验分享
2012/05/17 PHP
基于php实现长连接的方法与注意事项的问题
2013/05/10 PHP
php面象对象数据库操作类实例
2014/12/02 PHP
PHP addcslashes()函数讲解
2019/02/03 PHP
CI框架教程之优化验证码机制详解【验证码辅助函数】
2019/04/16 PHP
jQuery 定时局部刷新(setInterval)
2010/11/19 Javascript
Jquery插件之打造自定义的select标签
2011/11/30 Javascript
[JSF]使用DataModel处理表行事件的实例代码
2013/08/05 Javascript
JS控制网页动态生成任意行列数表格的方法
2015/03/09 Javascript
JavaScript实现常用二级省市级联下拉列表的方法
2015/03/25 Javascript
Javascript模仿淘宝信用评价实例(附源码)
2015/11/26 Javascript
利用Vue.js指令实现全选功能
2016/09/08 Javascript
完美解决jQuery fancybox ie 无法显示关闭按钮的问题
2016/11/29 Javascript
详解angularjs结合pagination插件实现分页功能
2017/02/10 Javascript
详解vue.js之props传递参数
2017/12/12 Javascript
jQuery实现列表的增加和删除功能
2018/06/14 jQuery
ES6的解构赋值实例详解
2019/05/06 Javascript
layui表格 列自动适应大小失效的解决方法
2019/09/06 Javascript
element表格翻页第2页从1开始编号(后端从0开始分页)
2019/12/10 Javascript
微信小程序实现列表的横向滑动方式
2020/07/15 Javascript
[01:14]TI珍贵瞬间系列(六):冠军
2020/08/30 DOTA
Python 命令行非阻塞输入的小例子
2013/09/27 Python
Python中__new__与__init__方法的区别详解
2015/05/04 Python
Python多线程爬虫实战_爬取糗事百科段子的实例
2017/12/15 Python
django-初始配置(纯手写)详解
2019/07/30 Python
Python使用python-docx读写word文档
2019/08/26 Python
详解使用Python下载文件的几种方法
2019/10/13 Python
使用python绘制二维图形示例
2019/11/22 Python
pytorch torchvision.ImageFolder的用法介绍
2020/02/20 Python
PyQT5 实现快捷键复制表格数据的方法示例
2020/06/19 Python
让IE6、IE7、IE8支持CSS3的脚本
2010/07/20 HTML / CSS
使用C#编写创建一个线程的代码
2013/01/22 面试题
地理科学专业毕业生求职信
2013/10/15 职场文书
老师自我鉴定范文
2013/12/25 职场文书
公司出差管理制度范本
2015/08/05 职场文书
OpenCV项目实践之停车场车位实时检测
2022/04/11 Python