php面向對象高級應用詳解(2)

魔術方法__get()實例詳解

在PHP中以兩個下劃線開頭的方法,被稱爲"魔術方法"(Magic methods)。比如__construct(), __destruct (), __clone(),以及__call(),,__get(), __set(),__sleep(), __wakeup(), __toString(), __autoload()等,都是魔術方法。

如果希望PHP調用這些魔術方法,首先必須在類中定義,否則PHP不會執行未創建的魔術方法。

注意:

魔術方法是php中設置好的,所以不能自己去創建,只能用php中本來就存在的,否則會報錯。

 

__get()的作用爲:

__get():讀取不可訪問屬性的值(private,protected,不存在)時,php就會執行__get()方法。

我們來看個有關__get()的實例:

<?php

class Person{
  public $name;
  protected $age;

  function __construct($name,$age){
    $this->name = $name;
    $this->age = $age;
  }

  function me(){
    echo $this->name.' '.$this->age;
  }

  //魔術方法
  function __get($pro){
    if(isset($this->$pro)){
      return $this->$pro;
    }else{
      echo '屬性值:'.$pro.'不存在';
    }
  }
}

$person = new Person('cyy',25);
$person->me();
echo '<br>';
echo $person->age;

 

魔術方法__set()實例詳解

__set()的作用:

__set():在給不可訪問屬性賦值(private,protected,不存在)時,php就會執行__set()方法。

 

<?php

class Person{
  public $name;
  protected $age;

  function __construct($name,$age){
    $this->name = $name;
    $this->age = $age;
  }

  function me(){
    echo $this->name.' '.$this->age;
  }

  //魔術方法
  function __get($pro){
    if(isset($this->$pro)){
      return $this->$pro;
    }else{
      echo '屬性值:'.$pro.'不存在';
    }
  }

  function __set($pro,$val){
    if(isset($this->$pro)){
      return $this->$pro = $val;
    }else{
      echo '屬性值不存在';
    }
  }
}

$person = new Person('cyy',25);
$person->me();
echo '<br>';
$person->age = '66';
echo $person->age;

 

因爲$age是保護的,所以不允許訪問。那麼,我們就要藉助__set()魔術方法來實現。__set()方法包含兩個參數,分別表示變量名稱和變量值,兩個參數不可省略。

 

魔術方法___toString()實例詳解

__toString()方法會先將對象傳化成字符串在輸出,這樣就可以用echo或者print輸出了。

實例分析:

 

<?php

class Person{
  public $name;
  protected $age;

  function __construct($name,$age){
    $this->name = $name;
    $this->age = $age;
  }

  //魔術方法
  function __get($pro){
    if(isset($this->$pro)){
      return $this->$pro;
    }else{
      echo '屬性值:'.$pro.'不存在';
    }
  }

  function __set($pro,$val){
    if(isset($this->$pro)){
      return $this->$pro = $val;
    }else{
      echo '屬性值不存在';
    }
  }

  function __toString(){
    return $this->name.' '.$this->age;
  }
}

$person = new Person('cyy',25);
echo $person;

 

結果如下:

cyy 25

如果實例化一個類,然後直接echo這個類名,頁面上會顯示報錯信息: Object of class xx could not be converted to string。意思是對象的類不能轉換爲字符串輸出。所以我們加上__toString()方法,就可以了,在方法中直接返回需要的結果就可以了。

 

魔術方法__call()實例詳解

什麼是__call()魔術方法?

__call是魔術方法中的一個,當程序調用到當前類中未聲明或沒權限調用的方法時,就會調用__call方法。__call()方法包含兩個參數,即方法名和方法參數。其中,方法參數是以數組形式存在的。

 

<?php

class Person{
  public $name;
  protected $age;

  function __construct($name,$age){
    $this->name = $name;
    $this->age = $age;
  }

  function __call($name,$arg){
    echo '當方法不存在時我會被調用<br>';
    echo '方法名:'.$name.', 參數爲:';
    var_dump($arg);
  }
}

$person = new Person('cyy',25);
$person->hh('a','b');

 

結果如下:

 

 

魔術方法__autoload()實例詳解

在寫代碼的時候,經常會遇到一個頭疼的問題,就是要在一個頁面中引入很多的類,需要用到include_once或者require_once()函數一個一個引入。當引入的內容不多時,還可以接受,但是如果有十幾個或者幾十個文件需要引入,操作次數多,煩躁不說,還會出現重複引入或者忘了引用的情況。

__autoload()方法可以自動實例化需要使用的類。當程序要用到一個類,但該類還沒有實例化時,PHP5將調用__autoload()方法,在指定的路徑下自動查找和該類名稱相同的文件。如果找到,程序則繼續執行;否則,報告錯誤。

注意:

其他所有的方法都是要在類的內部添加才起作用,__autoload()是唯一一個不在類中添加的方法

只要在頁面中使用到一個類,類名就會自動傳給這個參數。

舉個例子:

創建類文件person.class.php的代碼:

<?php

class Person{
  private $name;

  public function __construct($name){
    $this->name = $name;
  }

  public function __toString(){
    return $this->name;
  }
}

在index.php文件下的代碼:

<?php

function __autoload($class){
  $classpath = $class.'.class.php';
  if(file_exists($classpath)){
    include_once($classpath);
  }else{
    echo '類文件不存在';
  }
}

$person = new Person('cyy');
echo $person;

結果如下:

 

 

報錯是由於php版本過高,PHP 7.2開始不主張使用function __autoload(){}來自動加載類文件。

可以換低版本php,或者使用推薦的 spl_autoload_register 方法

---來自陳鶯鶯呀的分享

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章