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() 反序列化之前调用,可以预先执行一些准备操作,即便 __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 '
    '; } } // 实例化 $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

    当一个对象在执行字符串操作时应该返回什么值

    // 定义类
    class Example{
      // 字符串形态
      public function __toString(){
          return 'hello world';
      }
    }
    // 实例化
    $exam = new Example(['a', 'b', 'c']);
    
    // hello world
    echo $exam;
    
  • __invoke

    以函数形式调用已实例化的对象时,会执行该方法

    // 定义类
    class Example{
      // 函数式调用
      public function __invoke(string $str){
          return $str;
      }
    }
    // 实例化
    $exam = new Example();
    
    // hello world
    echo $exam('hello world');
    
  • __set_state
    执行 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
    执行 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);
    

你可能感兴趣的:(7.13 魔术方法)