??Php可以說是1個面向?qū)ο蟮恼Z言,php的類中有自己獨有的1些方法,不同于別的編程語言,php在定義類中除我們自己定義的屬性方法之外,Php還有1寫魔術(shù)方法,當我們把這些方法寫出來后,我們其實不需要自己去調(diào)用。系統(tǒng)就會在觸發(fā)某些條件以后自動調(diào)用。
??注意,當我們沒有寫這些魔術(shù)方法時,系統(tǒng)不會去調(diào)用這些魔術(shù)方法。
php提供的魔術(shù)方法有很多,這里我們只介紹經(jīng)常使用的幾個。
__get讀取不可訪問或不存在的屬性的值時,__get() 會被調(diào)用。
__set在給不可訪問或不存在的屬性賦值時,__set() 會被調(diào)用。
__isset() 當對不可訪問或不存在屬性調(diào)用 isset() 或 empty() 時,__isset() 會被調(diào)用。
__unset();當對不可訪問或不存在的屬性調(diào)用 unset() 時,__unset() 會被調(diào)用。
__call()在對象中調(diào)用1個不可訪問或不存在的方法時,__call() 會被調(diào)用。
__clone()可以避免他人克隆我們的對象。
??你會發(fā)現(xiàn)這些魔術(shù)方法的前面都有兩個下劃線__這是由于PHP 將所有以\ __(兩個下劃線)開頭的類方法保存為魔術(shù)方法。所以在定義類方法時,除上述魔術(shù)方法,建議不要以\ __ 為前綴。
下面我們單個的介紹每一個魔術(shù)方法是怎樣使用的。
??__get():讀取不可訪問或不存在的屬性的值時,__get() 會被調(diào)用。
??__set():在給不可訪問或不存在的屬性賦值時,__set() 會被調(diào)用。
??在類中當屬性的修飾符是protected和private的時候,在類的外部不能通過對象名的情勢進行訪問,如果強行讀取不可訪問的屬性,并且你在類的內(nèi)部寫了__get函數(shù),這時候候系統(tǒng)就會自動的調(diào)用__get魔術(shù)方法,當你強行修改不可訪問屬性值得時候,__set魔術(shù)方法就會被履行。
示例:
<?php
class Cat{
protected $name;
protected $age;
protected $sex;
public function __construct($name,$age,$sex){
$this -> name = $name;
$this -> age = $age;
$this -> sex = $sex;
}
//__set方法,可以處理你自己的邏輯
public function __set($name,$value){
echo 'set方法被履行了<br>';
//這里使用這個函數(shù)判斷當前類中有無這個屬性,避免屬性出現(xiàn)null的情況。
if(property_exists($this, $name)){
$this -> $name = $value;
}else{
echo '你要設(shè)置的屬性不存在';
}
}
//__get方法,可以處理你自己的邏輯
public function __get($name){
echo 'get方法被履行了<br>';
if(isset($this->$name)){
return $this -> $name;
}else{
echo '你要的屬性不存在,或?qū)傩灾禐榭?;
}
}
}
$cat = new Cat('小花',2,'雌');
echo $cat -> name . '<br>'; //讀取不可訪問的屬性值得時候,get方法被履行
$cat -> age = 5; //修改不可訪問的屬性值set方法被履行
echo $cat -> age;
property_exists()函數(shù):檢查對象或類是不是具有該屬性
??__isset():當對不可訪問或不存在屬性調(diào)用isset() 或 empty() 時,__isset() 會被調(diào)用。
??__unset():當對不可訪問或不存在的屬性調(diào)用 unset() 時,__unset() 會被調(diào)用。
??在類的外部對對象的不能訪問屬性使用isset函數(shù)或empty函數(shù)的時候或這個屬性在類中都沒有定義。魔術(shù)方法__isset()就會履行,而進行unset操作是__unset就會自動調(diào)用。
示例:
<?php
class Cat{
protected $name;
protected $age;
protected $sex;
public function __construct($name,$age,$sex){
$this -> name = $name;
$this -> age = $age;
$this -> sex = $sex;
}
//__isset方法,在類中可以對類的屬性進行判斷,并返回。
public function __isset($name){
echo 'isset方法履行了<br>';
return isset($this -> $name);
}
//__unset方法
public function __unset($name){
echo 'unset方法履行了<br>';
if(property_exists($this,$name)){
unset($this -> $name);
}else{
echo '你要燒毀的屬性不存在';
}
}
}
$cat = new Cat('小花',2,'雌');
echo isset($cat -> name);
unset($cat->age);
echo '<pre>';
var_dump($cat);
??__isset():在對象中調(diào)用1個不可訪問或不存在的方法時,__call() 會被調(diào)用。
??由于php語言不支持函數(shù)的重載,可使用這個魔術(shù)方法進行重載。
示例:
<?php
class Math{
private function add($a,$b){
return $a + $b;
}
private function add1($a,$b,$c){
return $a + $b + $c;
}
//這個魔術(shù)方法中有兩個參數(shù),第1個參數(shù)是傳過來的函數(shù)名,第2個參數(shù)是傳過來的方法中的參數(shù)組成的數(shù)組。
public function __call($method,$arr_value){
if($method == 'add'){
//得到數(shù)組的數(shù)量,肯定使用那個方法。
$total = count($arr_value);
if($total == 2){
return $this -> add($arr_value[0],$arr_value[1]);
}else if($total == 3){
return $this -> add1($arr_value[0],$arr_value[1],$arr_value[2]);
}
}
}
}
$math = new Math();
echo $math -> add(1,2) . '<br>';//私有的方法,沒有權(quán)限,會調(diào)用call方法.
echo $math -> add(1,2,3);
在php中同1類中1定不能有方法名相同的函數(shù)。不然后報錯。
??__clone():可以避免他人克隆我們的對象。
??php語言中有1種機制叫做克隆,如果定義了 __clone()方法,則新創(chuàng)建的對象(復(fù)制生成的對象)中的 __clone()方法會被調(diào)用。
程序員可以通過克隆把對象進行整體的克隆,但是有時我們不希望他人克隆我們的對象,比如單列模式,這時候使用克隆可以解決。
示例:
<?php
class Cat{
public $name;
public $age;
public function __construct($name,$age){
$this -> name = $name;
$this -> age = $age;
}
public function showInfo(){
echo '姓名是:' . $name . ' ' . '年齡是:' . $age;
}
private function __clone(){
}
}
$cat = new Cat('小花',2);
echo '<pre>';
var_dump($cat);
$cat2 = clone $cat;
var_dump($cat2);
??注意在這里魔術(shù)方法的權(quán)限修飾符是private,私有的。
??__tostring方法用于1個類被當做字符串時應(yīng)怎樣回應(yīng)。例如 echo $obj;
??當我們嘗試把1個對象當做字符換進行echo輸出的時候,類的tostring方法就會默許被調(diào)用,在這個方法中我們可以定義對象應(yīng)當輸出甚么。
示例:
<?php
class Dog{
private $name;
private $age;
private $color;
public function __construct($name,$age,$color){
$this -> name = $name;
$this -> age = $age;
$this -> color = $color;
}
//定義tostring方法
public function __toString(){
return '名字是:' . $this ->name . ' ' . '年齡是:' . $this -> age . ' ' . '色彩是:' . $this ->color;
}
}
$dog = new Dog('小白',4,'red');
echo $dog;
??注意:在tostring中必須要有1個返回值。
??__construct():PHP 5 允行開發(fā)者在1個類中定義1個方法作為構(gòu)造函數(shù)。具有構(gòu)造函數(shù)的類會在每次創(chuàng)建新對象時先調(diào)用此方法。
??在類中定義構(gòu)造函數(shù)1般是完成創(chuàng)建對象時,對象的初始化。當我們沒有定義構(gòu)造方法的時候,系統(tǒng)會調(diào)用他自己默許的構(gòu)造函數(shù),這個構(gòu)造函數(shù)是1個無參的構(gòu)造函數(shù)。
示例
<?php
class Cat{
protected $name;
protected $age;
protected $sex;
//定義1個構(gòu)造函數(shù),完成對屬性的初始化。
public function __construct($name,$age,$sex){
$this -> name = $name;
$this -> age = $age;
$this -> sex = $sex;
}
}
$cat = new Cat('小白',12,'雄');
echo '<pre>';
var_dump($cat);
??__destruct();PHP 5 引入了析構(gòu)函數(shù)的概念,析構(gòu)函數(shù)會在到某個對象的所有援用都被刪除或當對象被顯式燒毀時履行。
??析構(gòu)函數(shù)會在函數(shù)燒毀前履行,在這里面我們可以對用到的資源進行釋放,比如數(shù)據(jù)庫。
示例
<?php
class DaoMysql{
protected $link;
public function __construct($host,$user,$pwd){
$this -> link = @mysql_connect($host,$user,$pwd);
}
public function getLink(){
return $this -> link;
}
//析構(gòu)函數(shù),用來釋放數(shù)據(jù)庫資源。
public function __destruct(){
mysql_close($this->link);
}
}
$daoMysql = new DaoMysql('localhost','root','123456');
$sql = 'select * from tb1';
mysql_select_db('test');
mysql_query('set names utf8');
//通過對象的到里面的鏈接對象。
$res = mysql_query($sql,$daoMysql -> getLink());
echo '<pre>';
while($row = mysql_fetch_assoc($res)){
var_dump($row);
}
//當類中沒有析構(gòu)函數(shù)的時候,把對象置為空,下面的獲得數(shù)據(jù)還能履行,
//當類中有析構(gòu)函數(shù)的時候,把對象置為空,下面的獲得數(shù)據(jù)會出錯。說明成功的在析構(gòu)方法中把數(shù)據(jù)庫連接釋放掉了。
$daoMysql = null;
$res = mysql_query($sql);
echo '<pre>';
while($row = mysql_fetch_assoc($res)){
var_dump($row);
}
在php中,這些魔術(shù)方法大多數(shù)都是我們操作不可操作的數(shù)據(jù)時,系統(tǒng)觸發(fā)履行。區(qū)分于別的語言,也能夠說是php的1大特點。(- _ -);
上一篇 大數(shù)據(jù)系列修煉-Scala課程40
下一篇 使用外部容器運行spring-boot項目:不使用spring-boot內(nèi)置容器讓spring-boot項目運行在外部tomcat容器中