php clone wakeup,php 戏法方法

使用__call尝试调用一个不存在/不可用的成员方法

methodArray([0] => 1[1] => 2[2] => Hello[3] => HP)

__clone()

PHP5中的对象赋值是使用的引用赋值,如果想复制一个对象则需要使用clone方法,在调用此方法是对象会自动调用__clone魔术方法如果在对象复制需要执行某些初始化操作,可以在__clone方法实现

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 . "
";

$obj1 = clone $obj;

print $obj1->id . "
";

print $obj1->name . "
";

print $obj1->address . "
";

?>

输出:

11HelloNew York

__invoke()

当尝试以调用函数的方式调用一个对象时,__invoke 方法会被自动调用。PHP5.3.0以上版本有效

class CallableClass

{

public function __invoke($x)

{

var_dump($x);

}

}

$obj = new CallableClass;

$obj(5);

var_dump(is_callable($obj));

?>

输出:

int(5)

bool(true)

__sleep()、__wakeup()__sleep() 串行化的时候用__wakeup() 反串行化的时候调用

在PHP进行序列化时,serialize() 检查类中是否有 __sleep() , 如果有,则该函数将在任何序列化之前运行。该函数必须返回一个需要进行序列化保存的成员属性数组,并且只序列化该函数返回的这些成员属性. 该函数有两个作用: 第一. 在序列化之前,关闭对象可能具有的任何数据库连接等. 第二. 指定对象中需要被序列化的成员属性,如果某个属性比较大而不需要储存下来,可以不把它写进__sleep要返回的数组中,这样该属性就不会被序列化

相反地,unserialize() 从字节流中创建了一个对象之后,马上检查是否具有__wakeup 的函数的存在。如果存在,__wakeup 立刻被调用。使用 __wakeup 的目的是重建在序列化中可能丢失的任何数据库连接以及处理其它重新初始化的任务。

1)没有__sleep(), __wakeup()

class User {

public $name;

public $id;

function __construct() {

$this->id = uniqid (); //give user a unique ID 赋予一个不同的ID

}

}

$u = new User ();

$u->name = "HAHA";

$s = serialize ( $u ); //serialize it 串行化 注意不串行化id属性,id的值被抛弃

$u2 = unserialize ( $s ); //unserialize it 反串行化 id被重新赋值

var_dump ( $u );

var_dump ( $u2 );

?>

输出:

object(User)#1 (2) { ["name"]=> string(4) "HAHA" ["id"]=> string(13) "4f69980748589" } object(User)#2 (2) { ["name"]=> string(4) "HAHA" ["id"]=> string(13) "4f69980748589" }

2) __sleep(),serialize序列化"name"

class User {

public $name;

public $id;

function __construct() {

$this->id = uniqid (); //give user a unique ID 赋予一个不同的ID

}

function __sleep() {

return (array ("name")); //do not serialize this->id 不串行化id

}

}

$u = new User ();

$u->name = "HAHA";

$s = serialize ( $u ); //serialize it 串行化 注意不串行化id属性,id的值被抛弃

$u2 = unserialize ( $s ); //unserialize it 反串行化 id被重新赋值

var_dump ( $u );

var_dump ( $u2 );

?>

输出:

object(User)#1 (2) { ["name"]=> string(4) "HAHA" ["id"]=> string(13) "4f69995eebfb7" } object(User)#2 (2) { ["name"]=> string(4) "HAHA" ["id"]=> NULL }

3) __sleep(),serialize序列化"name"和"id"

function __sleep() {

return (array ("name, id")); //do not serialize this->id 不串行化id

}

输出:

object(User)#1 (2) { ["name"]=> string(4) "HAHA" ["id"]=> string(13) "4f699a67954c4" } object(User)#2 (2) { ["name"]=> string(4) "HAHA" ["id"]=> string(13) "4f699a67954c4" }

4) __wakeup(), 反序列化"id"

class User {

public $name;

public $id;

function __construct() {

$this->id = uniqid (); //give user a unique ID 赋予一个不同的ID

}

function __sleep() {

return (array ("name" )); //do not serialize this->id 不串行化id

}

function __wakeup() {

$this->id = uniqid (); //give user a unique ID

}

}

$u = new User ();

$u->name = "HAHA";

$s = serialize ( $u ); //serialize it 串行化 注意不串行化id属性,id的值被抛弃

$u2 = unserialize ( $s ); //unserialize it 反串行化 id被重新赋值

//$u and $u2 have different IDs $u和$u2有不同的ID

var_dump ( $u );

var_dump ( $u2 );

?>

输出:

object(User)#1 (2) { ["name"]=> string(4) "HAHA" ["id"]=> string(13) "4f699ab00ae11" } object(User)#2 (2) { ["name"]=> string(4) "HAHA" ["id"]=> string(13) "4f699ab00aec8" }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值