7.13 魔術方法

在PHP中內置了很多以__兩個下劃線開頭命名的方法,這些稱之為魔術方法。

  • __sleep
    可以在使用 serialize() 序列化之前,指明會被序列化的屬性,例如某個對象中的數據很大,但是只需要用到其中一部分,那么就可以用到 __sleep 了。

    // 定義類
    class Example{
      // 私有屬性
      private $foo = [1, 2, 3];
      private $bar = ['aa', 'bbb', 'cccc'];
      // 在序列化之前調用
      public function __sleep(){
          // 只序列化 bar 屬性
          return ["bar"];
      }
    }
    // 實例化
    $exam = new Example();
    
    // O:7:"Example":1:{s:12:"Examplebar";a:3:  {i:0;s:2:"aa";i:1;s:3:"bbb";i:2;s:4:"cccc";}}
    echo serialize($exam);
    
    // 如果沒有 __sleep 輸出的是:
    // O:7:"Example":2:{s:12:"Examplefoo";a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}s:12:"Examplebar";a:3:{i:0;s:2:"aa";i:1;s:3:"bbb";i:2;s:4:"cccc";}}
    
  • __wakeup
    在使用unserialize() 反序列化之前調用,可以預先執(zhí)行一些準備操作,即便 __sleep() 指明了僅序列化部分數據,但反序列后仍然能獲取所有數據

    // 定義類
    class Example{
      // 私有屬性
      private $foo = [1, 2, 3];
      private $bar = [];
      // 構造函數
      public function __construct(array $array){
          $this->bar = $array;
      }
      // 在序列化之前調用
      public function __sleep(){
          // 只序列化 bar 屬性
          return ["bar"];
      }
      // 在反序列化之前調用
      public function __wakeup(){
          echo '<br />';
      }
    }
    // 實例化
    $exam = new Example(['a', 'b', 'c']);
    
    // 序列化
    // string(80) "O:7:"Example":1:{s:12:"Examplebar";a:3:{i:0;s:1:"a";i:1;s:1:"b";i:2;s:1:"c";}}" 
    $data = serialize($exam);
    var_dump($data);
    
    // 返序列化
    // object(Example)#2 (2) { ["foo":"Example":private]=> array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } ["bar":"Example":private]=> array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" } }
    var_dump(unserialize($data));
    
  • __toString

    當一個對象在執(zhí)行字符串操作時應該返回什么值

    // 定義類
    class Example{
      // 字符串形態(tài)
      public function __toString(){
          return 'hello world';
      }
    }
    // 實例化
    $exam = new Example(['a', 'b', 'c']);
    
    // hello world
    echo $exam;
    
  • __invoke

    以函數形式調用已實例化的對象時,會執(zhí)行該方法

    // 定義類
    class Example{
      // 函數式調用
      public function __invoke(string $str){
          return $str;
      }
    }
    // 實例化
    $exam = new Example();
    
    // hello world
    echo $exam('hello world');
    
  • __set_state
    執(zhí)行 var_export() 時調用,該函數根據調用時第二個參數的值來決定輸出或返回一個字符串形式的變量。

    // 定義類
    class Example{
      // 我的屬性
      private $foo = 123;
      private $bar = 'abc';
      // var_export
      public static function __set_state(array $arr){
          return 'hello world';
      }
    }
    // 實例化
    $exam = new Example();
    
    // Example::__set_state(array( 'foo' => 123, 'bar' => 'abc', ))
    var_export($exam, false);
    
  • __debugInfo
    執(zhí)行 var_dump() 時,返回該對象的屬性集合

    // 定義類
    class Example{
      // 我的屬性
      private $foo = 123;
      private $bar = 'abc';
      // var_dump
      public function __debugInfo(){
          return [
              'foo'   =>  $this->foo,
              'bar'   =>  $this->bar . ' test',
          ];
      }
    }
    // 實例化
    $exam = new Example();
    // object(Example)#1 (2) { ["foo"]=> int(123) ["bar"]=> string(8) "abc test" }
    var_dump($exam);
    
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現,斷路器,智...
    卡卡羅2017閱讀 134,991評論 19 139
  • 把當前目錄作為Root Document只需要這條命令即可:php -S localhost:3300 也可以指定...
    絢爛的時光閱讀 747評論 0 1
  • Address:https://www.zybuluo.com/XiangZhou/note/208532 Exp...
    天蠍蒗漫閱讀 11,405評論 2 55
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,767評論 18 399
  • 人的一生中會面臨很多選擇,這只是大大小小的選擇中不起眼的一個,卻是你目前最嚴峻的考驗。我從來都不覺得讀書好代表有出...
    我是一么閱讀 224評論 1 2