您的位置:首页 > 编程语言 > PHP开发

[转]PHP5中 __call、__get、__set、__clone、__sleep、__wakeup的用法

2010-04-09 17:53 459 查看
PHP4
中已经有了重载的语法来建立对于外部对象模型的映射
,
就像
Java

COM
那样
. PHP5
带来了强大的面向对象重载
,
允许程序员建立自定义的行为来访问属性和调用方法,
php5
加入了如下的内部特征

__construct();
初始化
--
构造函数

__destruct();
卸载
--
析构函数

__get(); __get
方法可以用来捕获一个对象中不存在的变量和方法

__set(); __set
方法可以用来捕获和按参数修改一个对象中不存在的变量和方法

__call();
调用不存在的类的函数的时候得处理方法

__clone(); copy
对象用
clone $obj;

__sleep();
串行化的时候用

__wakeup();
反串行化的时候用

重载可以通过
__get,
__set, and __call
几个特殊方法来进行
.

Zend
引擎试图访问一个成员并没有找到时
,PHP
将会调用这些方法
.

在例
6.14

,__get

__set
代替所有对属性变量数组的访问
.
如果必要
,
你可以实现任何类型你想要的过滤
.
例如
,
脚本可以禁止设置属性值
,
在开始时用一定的前缀或包含一定类型的值
.

__call
方法说明了你如何调用未经定义的方法
.
你调用未定义方法时
,
方法名和方法接收的参数将会传给
__call
方法
, PHP
传递
__call
的值返回给未定义的方法
.

CODE: [Copy to clipboard]

--------------------------------------------------------------------------------

<?php

class foo {

function __set($name,$val) {

print("

Hello, you tried to put $val in $name");

}

function __get($name) {

print("

Hey you asked for $name");

}

}

$x = new foo();

$x->bar = 3;//
注意
$bar
不存在

print($x->winky_winky);

?>

CODE: [Copy to clipboard]

--------------------------------------------------------------------------------

<?php

class foo {

function __call($name,$arguments) {

print("Did you call me? I'm $name!");

}

} $x = new foo();

$x->doStuff(2);

$x->fancy_stuff('a string');

?>

这个特殊的方法可以被用来实现

过载
(overloading)”
的动作,这样你就可以检查你的参数并且通过调用一个私有的方法来传递参数。

使用
__call
实现

过载

动作

CODE: [Copy to clipboard]

--------------------------------------------------------------------------------

<?php

class Magic {

function __call($name,$arguments) {

if($name=='foo') {

print_r($arguments);

if(is_int($arguments[0]))
$this->foo_for_int($arguments[0]);

if(is_string($arguments[0]))
$this->foo_for_string($arguments[0]);

}

} private function foo_for_int($x) {

print("

oh an int!");

} private function foo_for_string($x) {

print("

oh a string!");

}

} $x = new Magic();

$x->foo(3);

$x->foo("3");

?>

对一个对象的拷贝通过调用对象的
__clone()
方法完成

CODE: [Copy to clipboard]

--------------------------------------------------------------------------------

<?php

$copy_of_object =clone $obj;

?>

CODE: [Copy to clipboard]

--------------------------------------------------------------------------------

<?php

class MyCloneable {

static $id = 0;

function MyCloneable() {

$this->id = self::$id+1; //
注意这里如果写
self::$id++;
将不被充许

}

function __clone() {

$this->address = "New York";

$this->id = self::$id+1;

}

}

$obj = new MyCloneable();

$obj->name = "Hello";

$obj->address = "Tel-Aviv";

print $obj->id . "

";

$obj =clone $obj;

print $obj->id . "

";

print $obj->name . "

";

print $obj->address . "

";

?>

串行化
serialize
可以把变量包括对象
,
转化成连续
bytes
数据
.
你可以将串行化后的变量存在一个文件里或在网络上传输
.
然后再反串行化还原为原来的数据
.
你在反串行化类的对象之前定义的类
,PHP
可以成功地存储其对象的属性和方法
.
有时你可能需要一个对象在反串行化后立即执行
.
为了这样的目的
,PHP
会自动寻找
__sleep

__wakeup
方法
.

当一个对象被串行化
,PHP
会调用
__sleep
方法
(
如果存在的话
).
在反串行化一个对象后
,PHP

会调用
__wakeup
方法
.
这两个方法都不接受参数
. __sleep
方法必须返回一个数组
,
包含需要串行化的属性
.
PHP
会抛弃其它属性的值
.
如果没有
__sleep
方法
,PHP
将保存所有属性
.

例子
6.16
显示了如何用
__sleep

__wakeup
方法来串行化一个对象
. Id
属性是一个不打算保留在对象中的临时属性
. __sleep
方法保证在串行化的对象中不包含
id
属性
.
当反串行化一个
User
对象
,__wakeup
方法建立
id
属性的新值
.
这个例子被设计成自我保持
.
在实际开发中
,
你可能发现包含资源
(
如图像或数据流
)
的对象需要这些方法

Object serialization

CODE: [Copy to clipboard]

--------------------------------------------------------------------------------

<?php

class User

{

public $name;

public $id;

function __construct()

{

//give user a unique ID
赋予一个不同的
ID

$this->id = uniqid();

}

function __sleep()

{

//do not serialize this->id
不串行化
id

return(array("name"));

}

function __wakeup()

{

//give user a unique ID

$this->id = uniqid();

}

}

//create object
建立一个对象

$u = new User;

$u->name = "Leon";

//serialize it
串行化
注意不串行化
id
属性
,id
的值被抛弃

$s = serialize($u);

//unserialize it
反串行化
id
被重新赋值

$u2 = unserialize($s);

//$u and $u2 have different IDs $u

$u2
有不同的
ID

print_r($u);

print_r($u2);

?>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐