1. 程式人生 > 其它 >php 魔術方法及觸發時機

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
)