php 魔术方法及触发时机

__get

对象访问受保护的属性,私有属性时,会触发__get魔术方法

<?php
class Person{
    //公有属性
    public $name;
    //受保护属性
    protected $age;
    //私有属性
    private $sex;

    //对象访问age,sex属性会访问这个方法
    public function __get($name){
        if($name == 'age'){
            return $this->age;
        }
        if($name == 'sex'){
            return $this->sex;
        }
    }
}

$boy = new Person();
//访问公有属性不会触发__get方法
echo $boy->name;
//访问受保护的属性会触发__get方法
echo $boy->age;
//访问私有属性会触发__get方法
echo $boy->sex;

__set

受保护的,私有的属性赋值会访问__set魔术方法

<?php
class Person{
    //公有属性
    public $name;
    //受保护属性
    protected $age;
    //私有属性
    private $sex;

    //age,sex属性赋值会访问这个方法
    public function __set($name, $value){
        if($name == 'age'){
            $this->age = $value;
        }
        if($name == 'sex'){
            $this->sex = $value;
        }
    }
}

$boy = new Person();
//公有属性赋值不会触发__set方法
$boy->name = '胡勇健';
//受保护的属性赋值会触发__set方法
$boy->age = 30;
//私有属性赋值会触发__set方法
$boy->sex = '男';

echo "<pre>";
var_dump($boy);

显示结果

object(Person)#1 (3) {
  ["name"]=>
  string(9) "胡勇健"
  ["age":protected]=>
  int(30)
  ["sex":"Person":private]=>
  string(3) "男"
}

__unset

受保护的,私有的属性删除会触发__unset

<?php
class Person{
    //公有属性
    public $name;
    //受保护属性
    protected $age;
    //私有属性
    private $sex;

    //unset受保护的,私有的属性删除会触发
    public function __unset($name){
        if($name == 'age'){
            unset($this->age);
        }
        if($name == 'sex'){
            unset($this->sex);
        }
    }
}

$boy = new Person();
//公有属性删除不会触发__unset方法
unset($boy->name);
//受保护的属性删除会触发__unset方法
unset($boy->age);
//私有属性删除会触发__unset方法
unset($boy->sex);

__isset

保护的,私有的属性isset会触发

<?php
class Person{
    //公有属性
    public $name;
    //受保护属性
    protected $age;
    //私有属性
    private $sex;

    //受保护的,私有的属性isset会触发
    public function __isset($name){
        if($name == 'age'){
            return isset($this->age);
        }
        if($name == 'sex'){
            return isset($this->sex);
        }
    }
}

$boy = new Person();
//公有属性不会触发
echo isset($boy->name);
//受保护的属性会触发
echo isset($boy->age);
//私有属性会触发
echo isset($boy->sex);

__construct

创建对象触发

<?php
class Person{
    //公有属性
    public $name;
    //受保护属性
    protected $age;
    //私有属性
    private $sex;

    //创建对象触发
    public function __construct($name,$age,$sex){
        $this->name = $name;
        $this->age = $age;
        $this->sex = $sex;
    }
}

//触发__construct方法
$boy = new Person('胡勇健',25,'男');
echo "<pre>";
print_r($boy);

结果显示

Person Object
(
    [name] => 胡勇健
    [age:protected] => 25
    [sex:Person:private] => 男
)

__destruct

对象销毁触发

<?php
class Person{
    //公有属性
    public $name;
    //受保护属性
    protected $age;
    //私有属性
    private $sex;

    //对象销毁触发
    public function __destruct(){
        echo '对象已销毁...';
    }
}


$boy = new Person();
echo $boy->name;

__toString

对象转换成字符串时触发

<?php
class Person{
    //公有属性
    public $name;
    //受保护属性
    protected $age;
    //私有属性
    private $sex;

    //对象转换成字符串时触发
    public function __toString(){
        return 'name:' . $this->name;
    }
}


$boy = new Person();
$boy->name = '胡勇健';
//触发__toString
echo $boy;

__call

访问受保护或私有方法时触发

<?php
class Person{

    //公有方法
    public function func1(){
        echo 'func1 is public<br>';
    }
    //受保护方法
    protected function func2(){
        echo 'func2 is protected<br>';
    }
    //私有方法
    private function func3($name,$age){
        echo 'func3 is private';
        echo 'name:' . $name .' ';
        echo 'age:' . $age;
    }

    //访问受保护或私有方法时触发
    public function __call($method, $arg_arr){
        if($method == 'func2'){
            $this->func2();
        }
        if($method == 'func3'){
            $name = $arg_arr[0];
            $age = $arg_arr[1];
            $this->func3($name, $age);
        }
    }
}


$boy = new Person();
//不会触发__call
$boy->func1();
//会触发__call
$boy->func2();
//会触发__call
$boy->func3('胡勇健', '35');

结果显示

func1 is public
func2 is protected
func3 is privatename:胡勇健 age:35

__callStatic

访问受保护或私有的静态方法时触发

<?php
class Person{

    //公有静态方法
    public static function func1(){
        echo "func1 is public<br>";
    }
    //受保护静态方法
    protected static function func2(){
        echo "func2 is protected<br>";
    }
    //私有静态方法
    private static function func3($name,$age){
        echo 'func3 is private';
        echo 'name:' . $name .' ';
        echo 'age:' . $age;
    }

    //访问受保护或私有的静态方法时触发
    public static function __callStatic($method, $arg_arr){
        if($method == 'func2'){
            self::func2();
        }
        if($method == 'func3'){
            $name = $arg_arr[0];
            $age = $arg_arr[1];
            self::func3($name, $age);
        }
    }
}


//不会触发__call
Person::func1();
//会触发__call
Person::func2();
//会触发__call
Person::func3('胡勇健', '35');

结果显示

func1 is public
func2 is protected
func3 is privatename:胡勇健 age:35

__sleep

对象被序列化时触发

<?php
class Person{

    public $name;
    public $age;

    //对象被序列化时触发
    public function __sleep(){
        return ['name','age'];
    }
}


$boy = new Person();
$boy->name = "胡勇健";
$boy->age = 28;

//触发__sleep
$string = serialize($boy);
var_dump($string);

结果显示

string(59) "O:6:"Person":2:{s:4:"name";s:9:"胡勇健";s:3:"age";i:28;}"

__wakeup

序列化的对象被反序列化时触发

<?php
class Person{

    public $name;
    public $age;

    //序列化的对象被反序列化时触发
    public function __wakeup(){
        echo '唤醒...';
    }
}

$string = 'O:6:"Person":2:{s:4:"name";s:9:"胡勇健";s:3:"age";i:28;}';

//触发__sleep
$boy = unserialize($string);
echo "<pre>";
print_r($boy);

结果显示

唤醒...
Person Object
(
    [name] => 胡勇健
    [age] => 28
)

__clone

克隆对象时触发

<?php
class Person{

    public $name;
    public $age;

    //克隆对象时触发
    public function __clone(){
        echo '我被克隆了...';
    }
}

$boy = new Person();
$boy->name = 'Huyongjian';
$boy->age  = 30;

//克隆对象触发__clone
$boy2 = clone $boy;
echo "<pre>";
print_r($boy2);

结果显示

我被克隆了...
Person Object
(
    [name] => Huyongjian
    [age] => 30
)