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

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);
?>

 

你可能感兴趣的:([转]PHP5中 __call、__get、__set、__clone、__sleep、__wakeup的用法)