、__wakeup 詳解
1、__call
__call( $method, $arg_array ) 當調用一個未定義的方法是調用此訪求
php教程5 的對象新增了一個專用方法 __call(),這個方法用來監視一個對象中的其它
方法。如果你試著調用一個對象中不存在的方法,__call 方法將會被自動調用。
例七:__call
class foo {
function __call($name,$arguments) {
print("did you call me? i'm $name!");
}
} $x = new foo();
$x->dostuff();
$x->fancy_stuff();
?>
這個特殊的方法可以被用來實現“過載(overloading)”的動作,這樣你就可以檢
查你的參數並且通過調用一個私有的方法來傳遞參數。
2、__autoload
__autoload 函數,它會在試圖使用尚未被定義的類時自動調用。
看下面的實例
寫好了一個msyql類,
mysql教程.php
class mysql{
funciton __construct(){
............
}
}
現在我在index.php頁面要用到mysql 類,我就這樣,function __authload($class){
include_once("path".$class.".php");
}$mysql=new mysql();
?>
include_once("path/".$class.".php");
path/ 是類文件所在路徑
$class 就是調用時的類名啦
後面的.php 當然是擴展名啦,
一個類文件可能感覺不到有多好用,如果類文件很多的時候,
每個類都要include一下,那太麻煩了,只要每個頁面之前寫一個 __autoload() 即
可,
通過調用此函數,腳本引擎在 php 出錯失敗前有了最後一個機會加載所需的類。
3、__construct、__destruct
構造函數與析構函數[__construct __destruct()]哦,他在在類class中的作用是
初始化與銷毀變量下面我們來看看實例以
class db
{
function __construct()
{
$this->mconnid=mysql_connect ($this->dbhost,$this->dbuser,$this->dbpwd);//建立連接
mysql_select_db($this->dbname, $this->mconnid); //選擇數
據庫
mysql_query("set names 'gbk'");//設置數據庫教程編碼為gbk
}
//__destruct:析構函數,斷開連接function __destruct()
{
mysql_close($this->mconnid); //此處還有問題......}
}
這時我們在用時就不需要考慮數據連接與關閉了,只要$aa = new db();就ok了。
更多詳細內容請查看:
http://www.bkjia.com/phper/18/aa7fc14039d6f49b02c646638588be7f.htm
4、__clone
__clone魔術方法
我們知道對象是可以直接賦值的,比如
$p2 = $p1; //這裡是一個對象有兩個引用
那麼我執行:
$p1->say();
$p2->say();
是都可以執行的,而且效果一樣。
我們還有一種方法:
$p3 = clone $p1; //注意clone是克隆關鍵字,這裡與上面的不同是$p3是一
個新的對象。
同時我們在類裡加入一個方法:
function __clone()
{
$this->name = “我是副本”; //注意:這裡的$this是克隆產生的對象本身,不是當前類
}然後我們執行:
$p3->say();
打印出
:
name:我是副本
age:20
到這裡我們明白,__clone()方法是在克隆對象的時候執行的方法,它的作用是對
新克隆出來的副本
進行屬性初始化等操作。
5、__tostring
__tostring方法在將一個對象轉化成字符串時自動調用
如果我有一個類:
class person
{
private $name = “”;
private $age = 0;function __construct($name = “”, $age = “”)
{
$this->name = $name;
$this->age = $age;
}function say()
{
echo “name:”.$this->name.”
”.”age:”.$this->age.”
”;
}
}
現在我去實例化這個類,然後去打印這個實例:
$p1 = new person(“liuzy”,20);
echo $p1; //直接打印會出錯
顯然這樣直接打印對象是會出現錯誤的,因為對象是引用句柄,不能直接打印。這
時,我們可以用到__tostring()方法。我們在person類裡加一個__tostring()方法
:
function __tostring()
{
return “i am person,my name is “.$this->name.”
”;
}
然後再刷新頁面,發現什麼了?
現在我們明白,__tostring()是在直接打印對象時執行的方法,我們可以用該方法
打印類的一些相關信息。注意:是兩個下劃線,方法必須有返回值
6、__sleep、__wakeup
__sleep 串行化的時候用
__wakeup 反串行化的時候調用
在php進行序列化時,serialize() 檢查類中是否有 __sleep() ,如果有,則該函
數將在任何序列化之前運行。該函數必須返回一個需要進行序列化保存的成員屬性
數組,並且只序列化該函數返回的這些成員屬性. 該函數有兩個作用: 第一. 在序
列化之前,關閉對象可能具有的任何數據庫連接等. 第二. 指定對象中需要被序列
化的成員屬性,如果某個屬性比較大而不需要儲存下來,可以不把它寫進__sleep要
返回的數組中,這樣該屬性就不會被序列化
相反地,unserialize() 從字節流中創建了一個對象之後,馬上檢查是否具有
__wakeup 的函數的存在。如果存在,__wakeup 立刻被調用。使用 __wakeup 的目
的是重建在序列化中可能丟失的任何數據庫連接以及處理其它重新初始化的任務。
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);
?>
---------- php debug ----------
object(user)#1 (2) {
["name"]=>
string(4) "haha"
["id"]=>
string(13) "47fa045529f69"
}
object(user)#2 (2) {
["name"]=>
string(4) "haha"
["id"]=>
string(13) "47fa04552a49a"
}