singleton
Singleton
<?php trait Singleton { protected static $instance; final public static function getInstance() { return isset(static::$instance) ? static::$instance : static::$instance = new static; } final private function __construct() { $this->init(); } protected function init() {} final private function __wakeup() {} final private function __clone() {} }
对象复制及__clone
赋值(实质是引用赋值) class myclass { public $data; } $obj1 = new myclass(); $obj1->data = "aaa"; $obj2 = $obj1; $obj2->data ="bbb"; //$obj1->data的值也会变成"bbb" 克隆(浅拷贝) class myclass { public $data; } $obj1 = new myclass(); $obj1->data ="aaa"; $obj2 = clone $obj1; $obj2->data ="bbb"; // $obj1->data的值仍然为"aaa" 引用 class myClass{ public $data; } $sss ="aaa"; $obj1 = new myClass(); $obj1->data =&$sss; //注意,这里是个reference! $obj2 = clone $obj1; $obj2->data="bbb"; //这时,$obj1->data的值变成了"bbb" 而不是"aaa"! 由于clone的shallow copy的特性,采用PHP中的 __clone方法 把浅拷贝转换为深拷贝 class testClass { public $str_data; public $obj_data; public function __clone() { $this->obj_data = clone $this->obj_data; } $dateTimeObj = new DateTime("2014-07-05", new DateTimeZone("UTC")); $obj1 = new testClass(); $obj1->str_data ="aaa"; $obj1->obj_data = $dateTimeObj; $obj2 = clone $obj1; var_dump($obj1); // str_data:"aaa" obj_data:"2014-07-05 00:00:00" var_dump($obj2); // str_data:"aaa" obj_data:"2014-07-05 00:00:00" $obj2->str_data ="bbb"; $obj2->obj_data->add(new DateInterval('P10D')); var_dump($obj1); // str_data:"aaa" obj_data:"2014-07-05 00:00:00" var_dump($obj2); // str_data:"aaa" obj_data:"2014-07-15 00:00:00" var_dump($dateTimeObj); //"2014-07-05 00:00:00"
序列化和反序列化构造对象
魔术方法__sleep: 用serialize() 函数实例化一个类的时候会检查类中是否存在一个魔术方法 __sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。 此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。如果该方法未返回任何内容, 则 NULL 被序列化,并产生一个 E_NOTICE 级别的错误。__sleep() 方法常用于提交未提交的数据,或类似的清理操作。 同时,如果有一些很大的对象,但不需要全部保存,这个功能就很好用。 魔术方法__wakeup: 与serialize()相反,unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法, 预先准备对象需要的资源。__wakeup() 经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。 class user { public $name; public $id; function __construct() { // 给id成员赋一个uniq id $this->id = uniqid(); } function __sleep() { //此处不串行化id成员 return(array('name')); } function __wakeup() { $this->id = uniqid(); } } $u = new user(); $u->name = "Leo"; $s = serialize($u); //serialize串行化对象u,此处不串行化id属性,id值被抛弃 $u2 = unserialize($s); //unserialize反串行化,id值被重新赋值